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