R 从大的错误中解脱出来`

R 从大的错误中解脱出来`,r,error-handling,R,Error Handling,由于其中一个值返回了一个错误,我丢失了整整3小时的地理编码运行,这可能会激发出这个问题,也可能不会。暗示同情(反对)投票 基本上,sapply调用的函数中返回了一个错误。我打开了选项(error=recover),但尽管浏览了我可用的每一个关卡,我还是找不到内存中存储(数千次成功)FUN调用结果的任何地方 我在浏览时发现的一些对象在我试图检查它们时出错,声称引用不再有效。不幸的是,我丢失了特定的错误消息 这里有一个简单的例子,虽然它没有复制引用错误(我怀疑这与消失的环境有关,可能无关紧要),但它

由于其中一个值返回了一个错误,我丢失了整整3小时的地理编码运行,这可能会激发出这个问题,也可能不会。暗示同情(反对)投票

基本上,
sapply
调用的函数中返回了一个错误。我打开了
选项(error=recover)
,但尽管浏览了我可用的每一个关卡,我还是找不到内存中存储(数千次成功)FUN调用结果的任何地方

我在浏览时发现的一些对象在我试图检查它们时出错,声称引用不再有效。不幸的是,我丢失了特定的错误消息

这里有一个简单的例子,虽然它没有复制引用错误(我怀疑这与消失的环境有关,可能无关紧要),但它确实表明我看不到保存已处理数据的方法

有这样的技巧吗

请注意,我已经意识到我的错误,并通过
try
插入了比以前更强大的错误处理,但我正在寻找一种方法来恢复内容事后而不是事前

测试功能

sapply( seq(10), function(x) {
  if(x==5) stop("Error!")
  return( "important data" )
} )
> sapply( seq(10), function(x) {
+   if(x==5) stop("Error!")
+   return( "important data" )
+ } )
Error in FUN(1:10[[5L]], ...) : Error!

Enter a frame number, or 0 to exit   

1: sapply(seq(10), function(x) {
    if (x == 5) 
        stop("Error!")
    return("important data")
})
2: lapply(X = X, FUN = FUN, ...)
3: FUN(1:10[[5]], ...)

Selection: 3
Called from: FUN(1:10[[5L]], ...)
Browse[1]> ls()
[1] "x"
Browse[1]> x
[1] 5
Browse[1]> 
Enter a frame number, or 0 to exit   

1: sapply(seq(10), function(x) {
    if (x == 5) 
        stop("Error!")
    return("important data")
})
2: lapply(X = X, FUN = FUN, ...)
3: FUN(1:10[[5]], ...)

Selection: 2
Called from: lapply(X = X, FUN = FUN, ...)
Browse[1]> ls()
[1] "FUN" "X"  
Browse[1]> X
 [1]  1  2  3  4  5  6  7  8  9 10
Browse[1]> FUN
function(x) {
  if(x==5) stop("Error!")
  return( "important data" )
}
Browse[1]> 
Enter a frame number, or 0 to exit   

1: sapply(seq(10), function(x) {
    if (x == 5) 
        stop("Error!")
    return("important data")
})
2: lapply(X = X, FUN = FUN, ...)
3: FUN(1:10[[5]], ...)

Selection: 1
Called from: sapply(seq(10), function(x) {
    if (x == 5) 
        stop("Error!")
    return("important data")
})
Browse[1]> ls()
[1] "FUN"       "simplify"  "USE.NAMES" "X"        
Browse[1]> X
 [1]  1  2  3  4  5  6  7  8  9 10
Browse[1]> USE.NAMES
[1] TRUE
Browse[1]> simplify
[1] TRUE
Browse[1]> FUN
function(x) {
  if(x==5) stop("Error!")
  return( "important data" )
}
Browser[1]> Q
交互式探索

sapply( seq(10), function(x) {
  if(x==5) stop("Error!")
  return( "important data" )
} )
> sapply( seq(10), function(x) {
+   if(x==5) stop("Error!")
+   return( "important data" )
+ } )
Error in FUN(1:10[[5L]], ...) : Error!

Enter a frame number, or 0 to exit   

1: sapply(seq(10), function(x) {
    if (x == 5) 
        stop("Error!")
    return("important data")
})
2: lapply(X = X, FUN = FUN, ...)
3: FUN(1:10[[5]], ...)

Selection: 3
Called from: FUN(1:10[[5L]], ...)
Browse[1]> ls()
[1] "x"
Browse[1]> x
[1] 5
Browse[1]> 
Enter a frame number, or 0 to exit   

1: sapply(seq(10), function(x) {
    if (x == 5) 
        stop("Error!")
    return("important data")
})
2: lapply(X = X, FUN = FUN, ...)
3: FUN(1:10[[5]], ...)

Selection: 2
Called from: lapply(X = X, FUN = FUN, ...)
Browse[1]> ls()
[1] "FUN" "X"  
Browse[1]> X
 [1]  1  2  3  4  5  6  7  8  9 10
Browse[1]> FUN
function(x) {
  if(x==5) stop("Error!")
  return( "important data" )
}
Browse[1]> 
Enter a frame number, or 0 to exit   

1: sapply(seq(10), function(x) {
    if (x == 5) 
        stop("Error!")
    return("important data")
})
2: lapply(X = X, FUN = FUN, ...)
3: FUN(1:10[[5]], ...)

Selection: 1
Called from: sapply(seq(10), function(x) {
    if (x == 5) 
        stop("Error!")
    return("important data")
})
Browse[1]> ls()
[1] "FUN"       "simplify"  "USE.NAMES" "X"        
Browse[1]> X
 [1]  1  2  3  4  5  6  7  8  9 10
Browse[1]> USE.NAMES
[1] TRUE
Browse[1]> simplify
[1] TRUE
Browse[1]> FUN
function(x) {
  if(x==5) stop("Error!")
  return( "important data" )
}
Browser[1]> Q
说清楚,我希望找到的是向量:

[1] "important data" "important data" "important data" "important data"
换句话说,已经完成的内部循环的结果到此为止

编辑:使用C代码更新

内部
.Internal(lappy())
是:

PROTECT(ans=allocVector(VECSXP,n));
...
对于(i=0;i

当对
lappy
的任何调用失败时,我想获得
ans

您从未将中间值分配给任何对象。我不明白你为什么认为应该有内脏来占卜。您需要以某种方式记录这些值:

 res <- sapply( seq(10), function(x) { z <- x
                                   on.exit(res <<- x);
                                   if(x==5) stop("Error!")
 } )
Error in FUN(1:10[[5L]], ...) : Error!
 res
#[1] 5

res也许我不明白,这肯定会让你慢下来,但每次都安排一个全局任务怎么样

safety <- vector()
sapply( seq(10), function(x) {
  if(x==5) stop("Error!")
  assign('safety', c(safety, x), envir = .GlobalEnv)
  return( "important data" )
} )
sapply(序号(10),功能(x){
+如果(x==5)停止(“错误!”)
+赋值('safety',c(safety,x),envir=.GlobalEnv)
+返回(“重要数据”)
+ } )
乐趣中的错误(1:10[[5L]],…):错误!
>安全
[1] 1 2 3 4

我很难理解为什么
try()
这里不是好办法?如果
sapply()
由于任何原因失败,那么您

  • 你想好好处理那次失败吗
  • 从那里继续
  • 为什么您希望整个数据分析/处理步骤仅因出现错误而停止?这就是你的建议。与其尝试恢复已经完成的工作,不如编写代码,这样它就可以继续进行,记录发生的错误,但也可以优雅地进入过程的下一步

    这有点令人费解,因为您给出的示例是人为的(如果您知道什么会导致错误,您可以在不使用
    try()
    的情况下处理该错误),但请记住:

    foo <- function(x) {
        res <- try({
            if(x==5) {
                stop("Error!")
            } else {
                "important data"
            }
        })
        if(inherits(res, "try-error"))
            res <- "error occurred"
        res
    }
    
    > sapply( seq(10), foo)
    Error in try({ : Error!
     [1] "important data" "important data" "important data" "important data"
     [5] "error occurred" "important data" "important data" "important data"
     [9] "important data" "important data"
    
    因为您想要的是列表,而不是将更复杂的对象简化为简单的对象:

    >     out <- lapply(seq(10), foo2)
    Error in try({ : Error!
    > str(out, max = 1)
    List of 10
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ : chr "error occurred"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
    
    >out str(out,max=1)
    10人名单
    $:12人名单
    ..-attr(*,“类”)=chr“lm”
    $:12人名单
    ..-attr(*,“类”)=chr“lm”
    $:12人名单
    ..-attr(*,“类”)=chr“lm”
    $:12人名单
    ..-attr(*,“类”)=chr“lm”
    $:chr“发生错误”
    $:12人名单
    ..-attr(*,“类”)=chr“lm”
    $:12人名单
    ..-attr(*,“类”)=chr“lm”
    $:12人名单
    ..-attr(*,“类”)=chr“lm”
    $:12人名单
    ..-attr(*,“类”)=chr“lm”
    $:12人名单
    ..-attr(*,“类”)=chr“lm”
    

    也就是说,我可能会通过一个
    for()
    循环来完成这项工作,在迭代时填写一个预先分配的列表。

    问得好!不久前我也遇到过类似的问题,想不出任何聪明的办法……所以我在每一步都添加了一行代码来编写一个.RDATA文件,所以我最终得到了一个目录,其中有100个.RDATA文件要读入,但恰恰避免了这个问题。是的。我实现了两个修复:一个是成批运行
    sapply
    ,共1000个,然后在其间保存。但现在这对我没有帮助:-/我猜现在唯一能帮你的是再过3个小时,很遗憾,由于Bing免费帐户有25k的地理编码配额,这将再过24个小时。因为你的问题是关于事后解决这个问题,这些不太适用,但未来的搜索者可能会对类似的问题感兴趣,这些问题显示了如何避免这个问题。见和;另请参见我的解决方案,其中包括一个版本的
    try
    ,这里:我不想要
    x
    的最后一个值。我希望函数生成的每个值都先于导致它失败的值<代码>sapply
    必须将其存储在某个地方。换句话说,我想要的是
    c(“重要数据”、“重要数据”、“重要数据”、“重要数据”)
    ,而不是
    c(5)
    。我认为
    sapply
    并没有存储它。你需要储存它。。。。呃他们@Tylerlinker的代码说明了一种方法。如果
    sapply
    (实际上,
    lappy
    ,在
    sapply
    内部调用)没有存储它,那么在没有错误的情况下它是如何神奇地出现的?它可能不存储在R代码中,但在
    内部版本中,有一个向量存储在我的结果中,goshdarnit:-)@AriB.Friedman——我想在这里以及你的包含C代码的编辑中,你已经回答了你自己的问题,那就是你无法从“R”中获得这些中间结果因为它们存储在名为
    ans
    的C变量中。我想,如果您在编译自己的R时启用了C级调试,您可能能够恢复错误并查看
    ans
    ,但我几乎不知道这是如何工作的。我完全不知道
    >     out <- lapply(seq(10), foo2)
    Error in try({ : Error!
    > str(out, max = 1)
    List of 10
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ : chr "error occurred"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"
     $ :List of 12
      ..- attr(*, "class")= chr "lm"