【问题标题】:R - tryCatch - use last iteration index to restart the for loopR - tryCatch - 使用最后一次迭代索引重新启动 for 循环
【发布时间】:2017-11-14 13:41:17
【问题描述】:

我已经阅读了有关 tryCatch() 的文档和其他几个问题,但是,我无法找出我的问题类别的解决方案。

要解决的任务是: 1)有一个从数据帧的第1行到第n行的for循环。 2)执行一些指令 3)如果出现错误会停止程序,而是从当前迭代重新开始循环循环。

例子

for (i in 1:50000) {
...execute instructions...
}

我正在寻找的是一个解决方案,在迭代 30250 出现错误的情况下,它会重新启动循环,这样

for (i in 30250:50000) {
...execute instructions...
}

我正在研究的实际示例如下:

library(RDSTK)
library(jsonlite)
DF <- (id = seq(1:400000), lat = rep(38.929840, 400000), long = rep( -77.062343, 400000)
for (i in 1 : nrow(DF) {
    location <- NULL
    bo <- 0
    while (bo != 10) {  #re-try the instruction max 10 times per row 
        location <- NULL
        location <- try(location <-  #try to gather the data from internet
                coordinates2politics(DF$lat[i], DF$long[i]))
        if (class(location) == "try-error") {  #if not able to gather the data
            Sys.sleep(runif(1,2,7))  #wait a random time before query again
            print("reconntecting...")
            bo <- bo+1                      
            print(bo)                 
        } else    #if there is NO error
            break   #stop trying on this individual
    }
    location <- lapply(location, jsonlite::fromJSON)
    location <- data.frame(location[[1]]$politics)
    DF$start_country[i] <- location$name[1]
    DF$start_region[i] <- location$name[2]
    Sys.sleep(runif(1,2,7))  #sleep random seconds before starting the new row
}

注意:try() 是“...执行指令...”的一部分

我正在寻找的是一个 tryCatch,当发生停止程序的严重错误时,它会从当前索引“i”重新启动 for 循环。

这个程序将允许我自动迭代超过 400000 行,并在出现错误时在中断的地方重新启动。这意味着该程序将能够完全由人类独立工作。

希望我的问题很清楚,非常感谢。

【问题讨论】:

  • 对于从 Internet 下载内容的情况,请使用 httr 包中的 RETRY()
  • 这对于其他类型的问题也是一个好主意。这里的问题不是从互联网收集数据,而是如何使用 tryCatch()(或其他一些函数)在出现错误的情况下从上一次迭代重新开始循环。

标签: r for-loop error-handling try-catch


【解决方案1】:

使用while 而不是for 更好地解决这个问题:

i <- 1
while(i < 10000){
  tryCatch(doStuff()) -> doStuffResults
  if(class(doStuffResults) != "try-catch") i <- i + 1
{

请注意,如果某些情况总是失败doStuff:循环将永远不会终止!

如果程序将产生致命错误并需要人工重启,那么第一行 i &lt;- 1 可以替换为(只要您不在代码的其他地方使用 i

if(!exists("i")) i <- 1

这样循环中的值将保持不变,不会被重置为 1。

【讨论】:

  • 我发布了真实示例的代码,以便您可以处理它并提供完整的答案。您能否将您的方法应用于具体问题?但是,请注意 try() 是 doStuff 的一个组件。例如,如果程序从 Internet 获取第 i 行的数据 10 次失败,那么程序会报错。此时,程序会中断,我应该手动重新启动它但是.. tryCatch 允许从那个单独的“i”重新启动 while 循环。
  • "我发布了真实示例的代码,以便您可以处理它并提供完整的答案。" - 金牌!你自己试试怎么样?
  • 当然我也在尝试自己做。我只是建议你可以给出这个问题的黄金答案,而不仅仅是一个提示。 :) 还是谢谢你
  • @Enrico:我正在尝试为您提出的一项非常具体的任务提供一般性答案。尽管考虑到您的程序可能会终止并且您希望使用相同的 i 值恢复,我已经添加了一个澄清点。另请注意,doStuff() 实际上不必是一个函数:您可以将 for 循环的主体粘贴为一组大括号表达式,这也可以。
  • @JDL 我无法使用您的方法,因为“错误:词法错误:json 文本中的无效字符”。仍然打破程序。有什么想法吗?
猜你喜欢
  • 2023-04-03
  • 2016-08-25
  • 2016-05-10
  • 2011-07-11
  • 1970-01-01
  • 1970-01-01
  • 2020-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多