2016-04-06 20 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() 

这是长于好像它需要,并运行,我可能不记得,以反映所做的任何更改的风险到底部的顶部。我宁愿做类似以下(非工作),但我不知道它是否可以这样做:

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

什么方法可以使%do% VS %dopar%的选择取决于arg函数?我想我可以注册一个核心并每次调用%dopar%,但是这会引发一个警告,说明没有注册并行后端,这可能会混淆不是我的人。

回答

3

下面的代码似乎工作。

(我因为我使用的是Windows机器使用doParallel代替doMC

这里的窍门是定义一个函数%fun%这或者取值%do%%dopar。这是可行的,因为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)