我必须对多个数据集进行分析。我使用plyr(mdply)和doSNOW包来使用多个核心。 有时分析代码会失败,引发错误并停止执行。我希望对其他数据集继续进行分析。怎么实现呢? 解决方案1:编码以便捕获所有错误,这是不可行的。 解决方案2:故障安全的plyr包装器并行运行该函数,返回所有有效结果,并指出出现问题的地方。
我实施了第二个解决方案(见下面的答案)。棘手的部分是我想要一个函数调用来完成failafe-and-return-a-data.frame功能。
我如何构建函数:
实际的函数调用包含tryCatch
。它是在callfailsafe
函数内调用的,而simple
函数则需要将(...)
中的单个函数名simple
和各个参数传递给整个过程。
也许我做得过于复杂......但它确实有效。
确保您的library(plyr)
library(doSNOW)
N=100
multiargtab= data.frame(ID=1:N,A=round(runif(N,0,1)),B=round(runif(N,0,1)))
simple=function(ID,A,B){ # a function that will sometimes fail
if(B==0) rm(B)
data.frame(A=A,B=B,AB=A/B,ID=ID)
}
函数不依赖于任何全局定义的函数或参数,因为与.parallel = T和doSNOW一起使用时不会加载它们。
这是我的测试数据集:有100个任务。对于每个函数,将调用“简单”。但有时功能失败。我通常在自动加载许多rdata文件的任务上进行大量处理,保存一些输出并最终返回data.frame对象。
res2=mdply.anyfun.parallel.failsafe(multiargtab,simple)
调用函数的签名是:
{{1}}
答案 0 :(得分:3)
函数mdply.anyfun.parallel.failsafe
将data.frame
和函数名myfunction
(作为字符)作为参数。然后为data.frame中的每一行调用myfunction
,并将所有列值作为参数传递,如原始mdply。除了原始mdply
功能外,该功能在任务失败时不会停止,而是继续执行其他任务。失败任务的错误消息将在“错误”列中返回。
library(doSNOW)
library(plyr)
mdply.anyfun.parallel.failsafe=function(multiargtab,myfunction){
cl<-makeCluster(4)
registerDoSNOW(cl)
callfailsafe=function(...){
r=tryCatch.W.E(FUN(...))
val=r$value[[1]]
if(!"simpleError" %in% class(val)){
return(val)
}else{
return(data.frame(...,error= (as.character(val))))
}
}
tryCatch.W.E=function(expr) {
#pass a function, it will be run and result returned; if error then error will return - BUT function will not fail
W <- NULL
w.handler <- function(w){ # warning handler
W <<- w
invokeRestart("muffleWarning")
}
list(value = list(withCallingHandlers(tryCatch(expr, error = function(e) e), warning = w.handler)), warning = W)
}
FUN=match.fun(myfunction)
res=mdply(multiargtab,callfailsafe,.parallel=T)
stopCluster(cl)
res
}
测试功能:
res2=mdply.anyfun.parallel.failsafe(multiargtab,simple)
一般都可以。当multiargtab类型为data.table
Error in data.table(..., key = key(..1)) :
Item 1 has no length. Provide at least one item
我通过强制转换为as.data.frame
来规避错误...虽然知道data.table为什么不起作用会很有趣。