R,dplyr和snow:如何并行化使用dplyr的函数

时间:2016-10-23 03:40:56

标签: r parallel-processing dplyr magrittr snow

假设我想以并行的方式将myfunction应用于myDataFrame的每一行。假设otherDataFrame是一个包含两列的数据框:COLUNM1_odfCOLUMN2_odf由于myfunction中的某些原因而使用。所以我想使用parApply编写代码,如下所示:

clus <- makeCluster(4)
clusterExport(clus, list("myfunction","%>%"))

myfunction <- function(fst, snd) {
 #otherFunction and aGlobalDataFrame are defined in the global env
 otherFunction(aGlobalDataFrame)

 # some code to create otherDataFrame **INTERNALLY** to this function
 otherDataFrame %>% filter(COLUMN1_odf==fst & COLUMN2_odf==snd)
 return(otherDataFrame)
}
do.call(bind_rows,parApply(clus,myDataFrame,1,function(r) { myfunction(r[1],r[2]) }

这里的问题是,即使我将COLUMN1_odf插入COLUMN2_odf,R也无法识别clusterExportsnow。我怎么解决这个问题?有没有办法去出口&#34; otherDataFrame需要的所有对象,以便不枚举每个对象?

编辑1:我已添加评论(在上面的代码中),以指定 myfunction 是在myfunction内部创建的。

编辑2:我添加了一些伪代码以概括aGlobalDataFrame:它现在使用全局数据框(otherFunction和另一个函数<html> <body> <div> <p>This is a confirmation message to confirm that you unsubscribed from the sci-eng email list.</p> <p>Click on the button below to confirm your unsubscription.</p> <form id="unsubform"> <div class="form-in"> <input type="hidden" id="emailkey" name="emailkey" value="key"> <input type="hidden" id="email" name="email" value="email@domain.com"> <button class="btn" id="submit" type="submit" formaction="http://redlinks.ca/sci-eng/db/unsubscribe.php" formmethod="post">Unsubscribe</button> </div> </form> </div> </body> </html>

2 个答案:

答案 0 :(得分:3)

完成了一些实验,所以我解决了我的问题(根据本杰明的建议并考虑了我已经添加到问题中的编辑内容):

clus <- makeCluster(4)
clusterEvalQ(clus, {library(dplyr); library(magrittr)})
clusterExport(clus, "myfunction", "otherfunction", aGlobalDataFrame)

myfunction <- function(fst, snd) {
 #otherFunction and aGlobalDataFrame are defined in the global env
 otherFunction(aGlobalDataFrame)

 # some code to create otherDataFrame **INTERNALLY** to this function
 otherDataFrame %>% dplyr::filter(COLUMN1_odf==fst & COLUMN2_odf==snd)
 return(otherDataFrame)
}

do.call(bind_rows, parApply(clus, myDataFrame, 1, 
        {function(r) { myfunction(r[1], r[2]) } )

通过这种方式,我注册了aGlobalDataFramemyfunctionotherfunction,简而言之就是用于并行化作业的函数所使用的所有函数和数据({{ 1}}本身)

答案 1 :(得分:0)

现在我不是在手机上看这个,我可以看到几个问题。

首先,您实际上并未在函数中创建otherDataFrame。您正尝试将现有otherDataFrame管道导入filter,如果环境中不存在otherDataFrame,则该功能将失败。

其次,除非您已将dplyr包加载到群集环境中,否则您将调用错误的filter函数。

最后,当您调用parApply时,您没有指定fstsnd应该是什么。试试以下内容:

clus <- makeCluster(4)
clusterEvalQ(clus, {library(dplyr); library(magrittr)})
clusterExport(clus, "myfunction")

myfunction <- function(otherDataFrame, fst, snd) {
 dplyr::filter(otherDataFrame, COLUMN1_odf==fst & COLUMN2_odf==snd)
}
do.call(bind_rows,parApply(clus,myDataFrame,1,function(r, fst, snd) { myfunction(r[fst],r[snd]), "[fst]", "[snd]") }