gpt4 book ai didi

r - plyr并行错误处理和警告

转载 作者:行者123 更新时间:2023-12-03 07:42:06 24 4
gpt4 key购买 nike

这是我用于错误处理的常见构造:

x <- tryCatch(foo(), error=function(e){
warning(e)
NULL})

我对许多数据对象运行foo,如果某些原因由于某些原因,它们可能会失败,如果我希望结果为NULL,这样我的整个运行就不会停止,但是我也想发出警告,以便可以看到什么失败了,为什么。

我经常像这样从plyr运行这些,让我们假设其中一些失败了:
x <- llply(1:4, .fun=function(i) {  
result<-tryCatch({
if(i %% 2==0) stop(i)
i}, error=function(e) {
warning(e)
NULL})
result})
x

结果:
 Warning messages:
1: In doTryCatch(return(expr), name, parentenv, handler) : 2
2: In doTryCatch(return(expr), name, parentenv, handler) : 4

> x
[[1]]
[1] 1

[[2]]
NULL

[[3]]
[1] 3

[[4]]
NULL

但是,假设我用相同的代码打开并行计算。
 require(doParallel)
registerDoParallel(cores=4)
x <- llply(1:4, .parallel=TRUE, .fun=function(i) {
result<-tryCatch({
if(i %% 2==0) stop(i)
i}, error=function(e) {
warning(e)
NULL})
result})

Result:
Error in do.ply(i) : task 2 failed - "2"

作业因任何任务中的错误而失败,并且未构造任何结果。警告(e)以某种方式转换为错误。我可以通过注释warning(e)来解决此问题,然后在出现错误时在数据结构中获得NULL的预期结果,但随后我会丢失有关发生的情况的信息。

实际上,我不知道从并行plyr发出警告的任何好方法。他们似乎被压制了。如果这是并行性的限制,那是有道理的。但是我认为警告变成错误行为很奇怪,我想了解这里发生了什么。

最佳答案

在我看来,用simpleError对象调用warning函数时出现问题。似乎工作正常:

> warning(simpleError(1))
Warning message:
1

但奇怪的是,在 tryCatch内部调用时,警告被视为错误:
> tryCatch({
+ warning(simpleError(1))
+ }, error=function(e) {
+ cat('caught an error\n')
+ print(class(e))
+ print(e)
+ })
caught an error
[1] "simpleError" "error" "condition"
<simpleError: 1>

由于 foreach包评估 tryCatch中的循环主体,因此认为发生了错误。例如:
> library(foreach)
> foreach(i=1:4) %do% warning(simpleError(1))
Error in warning(simpleError(1)) : task 1 failed - "1"

这意味着通过 .errorhandling='pass'选项将 .paropts选项传递给foreach应该可以防止错误中止 llply:
> x <- llply(1:4, .parallel=TRUE, .paropts=list(.errorhandling='pass'),
+ .fun=function(i) {
+ result<-tryCatch({
+ if(i %% 2==0) stop(i)
+ i}, error=function(e) {
+ warning(e)
+ NULL})
+ result})
> x
[[1]]
[1] 1

[[2]]
<simpleError in doTryCatch(return(expr), name, parentenv, handler): 2>

[[3]]
[1] 3

[[4]]
<simpleError in doTryCatch(return(expr), name, parentenv, handler): 4>

看起来您可以通过在调用 warning之前将simpleError对象的类更改为simpleWarning来解决此问题:
x <- llply(1:4, .parallel=TRUE,
.fun=function(i) {
result<-tryCatch({
if(i %% 2==0) stop(i)
i}, error=function(e) {
class(e) <- class(simpleWarning(''))
warning(e)
NULL})
result})

如果要在顺序或并行运行时获取警告,则可以将错误对象转换为警告对象,并将其与其他结果一起返回。例如:
x <- llply(1:4, .parallel=TRUE, .fun=function(i) {
result<-tryCatch({
if(i %% 2==0) stop(i)
i}, error=function(e) {
class(e) <- class(simpleWarning(''))
e})
result})

for (i in seq_along(x)) {
if (inherits(x[[i]], 'simpleWarning')) {
warning(x[[i]])
x[i] <- list(NULL)
}
}

关于r - plyr并行错误处理和警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27533164/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com