如何并行执行故障安全执行plyr mdply

时间:2013-06-24 11:16:02

标签: r parallel-processing plyr

我必须对多个数据集进行分析。我使用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}}

1 个答案:

答案 0 :(得分:3)

函数mdply.anyfun.parallel.failsafedata.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为什么不起作用会很有趣。