2013-06-24 32 views
2

我必須在多個數據集上運行分析。我使用帶有doSNOW包的plyr(mdply)來使用多個內核。 有時分析代碼會失敗,引發錯誤並停止執行。我希望對其他數據集繼續進行分析。如何實現這一目標? 解決方案1:編碼以便捕獲所有不可行的錯誤。 解決方案2:故障安全plyr包裝器並行運行該函數,返回所有有效結果,並指出出錯的地方。如何使用plyr mdply並行執行故障安全

我實施了第二種解決方案(請參閱下面的答案)。棘手的部分是我想要一個函數調用來完成故障安全和返回數據幀功能。

我如何去構造函數: 實際的函數調用是用tryCatch包裝的。它是在callfailsafe函數中調用的,而函數又需要將單個函數名稱simple(...)中的相應參數傳遞給整個過程。 也許我做得太複雜了...但它有效。

確保您的simple函數不依賴於任何全局定義的函數或參數,因爲這些函數在使用.parallel = T和doSNOW時不會加載。

這是我的測試數據集:有100個任務。對於每個函數「簡單」將被調用。但有時候這個功能會失敗。我通常在自動加載許多rdata文件的任務上使用它,執行大量處理,保存一些輸出並最終返回一個data.frame對象。

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) 
} 

調用函數的簽名是:

res2=mdply.anyfun.parallel.failsafe(multiargtab,simple) 
+0

你也可以用'try'而不是'tryCatch';它要簡單得多,而且通常都是需要的。 –

回答

3

功能mdply.anyfun.parallel.failsafedata.frame和作爲參數的functionname 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是行不通的。

+1

這是你自己問題的答案嗎?如果是這樣的話,我建議你添加幾行關鍵部分的解釋。否則,你的答案對其他人沒有幫助。但是,如果這只是提供了上述問題的其他信息,那麼我建議您減少代碼量並將其餘內容放入問題主體中。 – Thilo

+0

@Thilo建議採取。縮短了例子。我發佈了它,因爲我認爲這是一個普遍的問題,這已經困擾了我一段時間......但如果我的解決方案不明白,發佈它就沒有意義了。我希望它現在變得更清晰。感謝您的評論。 –

+0

太棒了!這是我希望看到的。將-1更改爲+1;) – Thilo