2

複数のデータセットに対して分析を実行する必要があります。複数のコアを使用するには、doSNOW パッケージで plyr (mdply) を使用します。分析コードが失敗し、エラーが発生して実行が停止することがあります。他のデータセットについても分析を続けてほしい。それを達成する方法は?解決策 1: すべてのエラーがキャッチされるようにコーディングしますが、これは実現不可能です。解決策 2: すべての有効な結果を返し、どこで問題が発生したかを示す、関数を並列で実行するためのフェールセーフ plyr ラッパー。

2番目のソリューションを実装しました(以下の回答を参照)。注意が必要なのは、1 つの関数呼び出しでフェイルセーフと return-a-data.frame 機能を実現したかったことです。

関数の作成方法: 実際の関数呼び出しは でラップされ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)
4

1 に答える 1

3

この関数mdply.anyfun.parallel.failsafeは、パラメータとして adata.frameおよび functionname myfunction(文字として) を取ります。myfunction次に、data.frame のすべての行に対して呼び出され、すべての列の値を元の 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 が機能しない理由を知ることは興味深いでしょう。

于 2013-06-24T11:16:02.357 に答える