%dopar%
並列環境内で複数レベルのdo.call
をそれぞれネストしています私の外部環境からの関数は、最も内側の関数では見つけることができません。私はの.export
パラメータについて知っていますが、それを使用していますが、何らかの形で名前付きファンクションがチェーン全体に伝播していません。foreach%dopar%環境内でネストされたdo.callが.exportで渡された関数を見つけることができません
私はこの問題は発生しません、次のテストケースに私の問題を軽減:
library(doParallel)
cl <- makeCluster(4)
registerDoParallel(cl)
simple.func <- function(a, b) {
return(a+b)
}
inner.func <- function(a, b) {
return(do.call(simple.func, list(a=a, b=b)))
}
outer.func <- function(a, b, my.func=inner.func) {
return(do.call(my.func, list(a=a, b=b)))
}
main.func <- function(my.list=1:10, my.func=outer.func,
my.args=list(my.func=inner.func)) {
results <- foreach(i=my.list, .multicombine=TRUE, .inorder=FALSE,
.export="simple.func") %dopar% {
return(do.call(my.func, c(list(a=i, b=i+1), my.args)))
}
return(results)
}
よりもむしろ正しい答え(一部番号のリスト)を与え、私が手:
Error in { : task 1 failed - "object 'simple.func' not found"
outer.func
がであっても、if (!exists("simple.func")) stop("Could not find parse.data in scope main.func")
をそれぞれの関数の先頭に追加すると(スコープの名前を適切に変更すると)が表示されません。それを見てください。
また、パラメータから使用するのではなく、次のレベルの関数がハードコードされているmain.func
またはouter.func
の2つのバリエーションをテストしました。これらのバリエーションの両方はです(例えば、期待される結果を出す)が、実際のケースでは、サブ関数をパラメータとして取ることの一般性を保持したいと思います。
# Variation number one: Replace main.func() with this version
main.func <- function(my.list=1:10, my.func=outer.func,
my.args=list(my.func=inner.func)) {
results <- foreach(i=my.list, .multicombine=TRUE, .inorder=FALSE,
.export=c("simple.func", "outer.func", "inner.func")) %dopar% {
return(do.call(outer.func, list(a=i, b=i+1, my.func=inner.func)))
}
return(results)
}
# Variation number two: Replace outer.func() and main.func() with these versions
outer.func <- function(a, b, my.func=inner.func) {
return(do.call(inner.func, list(a=a, b=b)))
}
main.func <- function(my.list=1:10, my.func=outer.func,
my.args=list(my.func=inner.func)) {
results <- foreach(i=my.list, .multicombine=TRUE, .inorder=FALSE,
.export=c("simple.func", "inner.func")) %dopar% {
return(do.call(my.func, c(list(a=i, b=i+1), my.args)))
}
return(results)
}
私はまた、追加のパラメータとして、それを含めることによって、手動でチェーンダウンsimple.func
を渡すことができますが、これは余分な乱雑に見える、とsimple.func
はちょうど環境の一部として渡されなければならない時に、なぜそれが必要になるでしょうか?
# Variation number three: Replace inner.func(), outer.func(), and main.func()
# with these versions
inner.func <- function(a, b, innermost.func=simple.func) {
return(do.call(innermost.func, list(a=a, b=b)))
}
outer.func <- function(a, b, my.func=inner.func,
innermost.args=list(innermost.func=simple.func)) {
return(do.call(my.func, c(list(a=a, b=b), innermost.args)))
}
main.func <- function(my.list=1:10, my.func=outer.func,
my.args=list(my.func=inner.func,
innermost.args=list(innermost.func=simple.func))) {
results <- foreach(i=my.list, .multicombine=TRUE, .inorder=FALSE,
.export="simple.func") %dopar% {
return(do.call(my.func, c(list(a=i, b=i+1), my.args)))
}
return(results)
}
誰もが、この問題の根本的な原因ではないかと思われますか? doParallel
については
あなたのコードはそれらのコードでいっぱいです:すべての 'return'呼び出しは不要です。 Rは関数内の最後の式の値を自動的に返します。関数を途中で残すには 'return'が必要です。 –