2017-09-19 5 views
0

nested foreachループ内に最上位関数を含むR packageを構築しようとしています。このトップレベル関数は、さらにネストされた関数のセットを呼び出します。私が持っている問題はレキシカルスコープであり、低レベルの関数は変数や変数を置く環境を見つけることができません。私はこの例ではattachのようにattachを使用しようとしましたが、より低い関数でも必要な引数を見ることができません。私は、フォークメソッドを使ってdoMPIに固有の何かがあることを知っています。これはdoMPI(0.2.2)とforeach(1.4.3)とopenmpiを使って、Ubuntu Linux(16.04)にあります。これは、私が持っているはるかに大きなモデルのmweです。パッケージと実行/テストするスクリプトはtoymod4 packageと呼ばれています。foreachループの内部で変数や環境が見つからない関数

#' Test function level 1 
#' @param num.sim first variable for function 1 
#' @param num.per second variable for function 1 
#' @param num.day third variable for function 1 
#' @param fun2.params parameters for function 2 
#' @param fun31.params parameters for first call of function 3 
#' @param fun32.params parameters for second call of funtion 3 
#' @param fun4.params parameters for call to function 4 
#' @export fun1 
fun1 <- function (fun2.params, fun31.params, fun32.params, fun4.params, 
        num.sim=10, num.per=8, num.day=5, ...) { 
    final.results <- data.frame (foreach::`%dopar%`(
     foreach::`%:%`(foreach::foreach(j = 1:num.sim, 
             .combine = cbind, 
             .packages= c("toymod4")), 
         foreach::foreach (i = 1:num.per, 
             .packages = c("toymod4"), 
             .combine=rbind)), { 
      e1 <- new.env() 
      e1 <- list2env(c(fun2.params, fun31.params, fun32.params, 
          fun4.params), e1) 
      out3 <- replicate(num.day, fun2(e1, var21, var22, fun22on)) 
      out2 <- data.frame(mean(out3)) 
     } 
    ) 
    ) 
    ## save outputs for subsequent analyses if required 
    saveRDS(final.results, file = paste(num.day ,"_", num.per, "_", num.sim, "_", 
             format(Sys.time(), "%d_%m_%Y"), 
             ".rds", sep="")) 
    return(final.results) 
} 

#' Test function level 2 
#' @param var21 first variable for function 2 
#' @param var22 second variable for function 2 
#' @param fun22on turn this copy of fun3 on or off 
#' @param env environment to get variables from 
#' @export fun2 
fun2 <- function (env, var21, var22, fun22on, ...) { 
    attach(env) 
    out21 <- ifelse (rpois(1, var21) > 0, var22 * fun3(e1, fun3on, var31), 0) 
    out22 <- ifelse (fun22on, fun3(e1, fun3on, var31), 0) 
    out2 <- out21 + out22 
    detach(env) 
    out2 
} 

#' Test function level 3 
#' @param var31 first variable for function 3 
#' @param fun3on turn the formula on or off 
#' @export fun3 
fun3 <- function (env, fun3on, var31, ...) { 
    attach(env) 
    out31 <- ifelse (fun3on, var31, 1) 
    out32 <- ifelse (fun3on, fun4(e1, fun4on, var41), 0) 
    out3 <- out31 + out32 
    detach(env) 
    out3 
} 

#' Test function level 4 
#' @param var41 first variable for function 4 
#' @param fun4on turn the formula on or off 
#' @export fun4 
fun4 <- function (env, fun4on, var41, ...) { 
    attach(env) 
    out4 <- ifelse (fun4on, var41, 1) 
    detach(env) 
    out4 
} 
+0

あなたは何を試しましたか?どの議論に?私がすでに似たような質問に答えていると思います。 –

+0

彼らは似ているが同じではないので、私はそれが答えられたとは思わない。私はまだすべての引数をすべての関数に渡すことを避けようとしています。実際のモデルでは、80個の引数を最初の関数に渡し、75個を2番目の関数に渡すことを意味します。私が環境を制限する方法を見つけ出すことができれば、その中で働いています。そして、doMPIはdoParallelと同義ではありません。コールは複雑で、このコメントに追加するツールは大きいですが、githubのドライバファイルにあります。ごめんなさい。 –

答えて

0

スティーブウェストンの寛大な助けを借りて、私はこの問題を解決することができました。それをすべて説明しようとするよりも、私はこのアドレスのgithubに投稿しました https://github.com/jamaas/VarPasMpiExamp.git foreachループ内に含まれる関数に変数値を渡す方法の1つです。理論的には、任意のオペレーティングシステム上で、任意の並列バックエンドを使用してforeachを実行する必要がありますが、まだすべてでテストされていません。このバージョンの開発とテストは、Ubuntu 16.04(Debian)Linuxで行われました。この方法が効果的かどうか、特にシンプルで洗練されたソリューションがあれば教えてください。

関連する問題