2016-04-06 14 views
3

私は、ユーザにパラレルで実行するかどうかを指定する関数を書いています。競合他社にはさまざまな理由でforeachが好きです。これまでのところ、私はそれが以下のダミー関数と同様に設定持っている:関数への引数に基づいて%do%vs%dopar%(foreach)を呼び出す

library(foreach) 
myfun <- function(parallel = TRUE){ 
    if (parallel == TRUE){ 
    require(doMC) 
    registerDoMC(detectCores()) 
    foreach(i = 1:10) %dopar% { 
     print(i) 
    } 
    } else { 
    foreach(i = 1:10) %do% { 
     print(i) 
    } 
    } 
    return('OK!') 
} 
myfun() 

これは、それがあることが必要であるように思える、と私が行った変更を反映するために覚えていないかもしれない危険を冒すよりも長いです下の上に移動します。私は、次の(非稼働)のような何かを行うことを好むだろうが、そうすることが可能であるならば、私にはわからない:%dopar%%do%の選択をすることに依存する

myfun <- function(parallel = TRUE){ 
    if (parallel == TRUE){ 
    require(doMC) 
    registerDoMC(detectCores()) 
    } 
    foreach(i = 1:10) ifelse(parallel == TRUE, %dopar%, %do%) { 
    print(i) 
    } 
    return('OK!') 
} 

どれかの方法を関数へのarg?私はちょうど1コアを登録して毎回%dopar%と呼ぶことができると思いますが、それは並列バックエンドが登録されていないという警告をスローして、私ではない人を混乱させるかもしれません。

答えて

3

次のコードが機能するようです。

(私はWindowsマシンを使用していますので、私はdoParallel代わりのdoMCを使用していました。)

ここでのトリックは値%do%%doparのいずれかを取る関数%fun%を定義することです。これはRの関数がファーストクラスのオブジェクトであり、既存の関数の値を新しい関数に割り当てることができるため機能します。小さな詳細は、%do%をバッククォートで囲む必要があることです。

library(foreach) 
require(doParallel) 

foo <- function(parallel = TRUE){ 
    `%fun%` <- `%do%` 
    if (parallel == TRUE){ 
    require(doParallel) 
    cl <- makePSOCKcluster(detectCores()) 
    registerDoParallel(cl) 
    `%fun%` <- `%dopar%` 
    } 
    foreach(i = 1:10) %fun% { 
    print(i) 
    } 
    return('OK!') 
} 

foo(FALSE) 
foo(TRUE) 
関連する問題