Snowfall ライブラリとその使用法について頭を悩ませようとしています。
環境を利用するシミュレーションを書いていると、次の問題が発生しました。並列モード内で関数をロードするためにファイルをソースすると、関数は、並列モード内で関数を直接宣言したときとは異なる環境を使用しているように見えます。
もう少しわかりやすくするために、次の 2 つのスクリプトについて考えてみましょう。
q_func.Rは関数を宣言します
foo.bar <- function(x, envname) assign("val", x, envir = get(envname))
# assigns the value x to the variable "val" in the environment envname
q_snowfall.R降雪を利用したメイン関数
library(snowfall)
SnowFunc <- function(envname) {
# load the functions
# Option 1 not working
source("q_func.R")
# Option 2 working...
# foo.bar <- function(x, envname) assign("val", x, envir = get(envname))
# create the new environment
assign(envname, new.env())
# use the function as declared in q_func.R
# to assign random numbers to the new env
foo.bar(x = rnorm(1), envname = envname)
# return the environment including the random values
return(get("val", envir = get(envname)))
}
sfInit(parallel = TRUE, cpus = 2)
# create environment 'a' and 'b' that each will get a new variable
# called 'val' that gets assigned a random value
envs <- c("a", "b")
result <- sfClusterApplyLB(envs, SnowFunc)
sfStop()
スクリプト「q_snowfall.R」を実行すると、エラーが発生します
Error in checkForRemoteErrors(val) :
2 nodes produced errors; first error: object 'a' not found
ただし、2 番目のオプション (SnowFunc 関数内で関数を宣言する) を使用すると、エラーは消えます。
Snowfall がさまざまな環境をどのように処理するか知っていますか? または、問題の解決策さえありますか。(「q_func.R」は実際には約 100 行のコードを必要とすることに注意してください。したがって、別のファイルに保存することをお勧めします。したがって、「オプション 2 を保持する」は解決策ではありません!)
どうもありがとうございました!
編集
すべてを変更するget(envname)
とget(envname, envir = globalenv())
、うまくいくようです。しかし、これは多かれ少なかれ回避策であり、降雪のような解決策ではないように思えます。