这个问题可能会或可能不会受到我失去整个3小时地理编码运行的启发,因为其中一个值返回了错误。提示怜悯(下)投票。
基本上在sapply
调用的函数中返回了一个错误。我有options(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
要清楚,我希望找到的是矢量:
[1] "important data" "important data" "important data" "important data"
换句话说,到目前为止已经完成的内部循环的结果。
编辑:使用C代码更新
内部.Internal(lapply())
是following code:
PROTECT(ans = allocVector(VECSXP, n));
...
for(i = 0; i < n; i++) {
...
tmp = eval(R_fcall, rho);
...
SET_VECTOR_ELT(ans, i, tmp);
}
当ans
的任何来电失败时,我想lapply
。
答案 0 :(得分: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"
在后台运行我的工作站需要几周才完成的工作后,我很快学会了围绕单个语句编写大量try()
个调用而不是大块代码,这样一旦发生错误,我很快就会得到超出该迭代/步骤,对正在运行的作业影响最小;换句话说,如果一个特定的R调用失败,我会返回一些内容,这些内容会很好地插入sapply()
(或任何函数)返回的对象中。
对于任何更复杂的事情,我可能会使用lapply()
:
foo2 <- function(x) {
res <- try({
if(x==5) {
stop("Error!")
} else {
lm(rnorm(10) ~ runif(10))
}
})
if(inherits(res, "try-error"))
res <- "error occurred"
res
}
out <- lapply(seq(10), foo2)
str(out, max = 1)
因为你想要列表而不是试图将更复杂的对象简化为简单的东西:
> 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"
那就是说,我可能已经通过for()
循环完成了这项工作,在迭代时填写预分配列表。
答案 1 :(得分:1)
您从未将中间值分配给任何内容。我不明白为什么你认为应该有任何内脏。您需要以某种方式记录值:
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
此on.exit
方法在?par
页面上说明,作为在绘图出错时恢复标准设置的方法。 (我无法使用on.exit(res <- x)
。
答案 2 :(得分:1)
也许我不理解,这肯定会减慢你的速度,但每次全球任务呢?
safety <- vector()
sapply( seq(10), function(x) {
if(x==5) stop("Error!")
assign('safety', c(safety, x), envir = .GlobalEnv)
return( "important data" )
} )
收率:
> safety <- vector()
> sapply( seq(10), function(x) {
+ if(x==5) stop("Error!")
+ assign('safety', c(safety, x), envir = .GlobalEnv)
+ return( "important data" )
+ } )
Error in FUN(1:10[[5L]], ...) : Error!
> safety
[1] 1 2 3 4