假设我想以并行方式将myfunction
应用于myDataFrame
的每一行。假设otherDataFrame
是一个有两列的数据帧:COLUNM1_odf
和COLUMN2_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
插入到clusterExport
中,R也无法识别它们。我该如何解决这个问题?有没有一种方法可以"导出"snow
需要的所有对象,从而不枚举它们中的每一个?
第1版:我添加了一个注释(在上面的代码中(,以便指定otherDataFrame
是在myfunction
的内部创建的。
第2版:为了推广myfunction
,我添加了一些伪代码:它现在使用全局数据帧(aGlobalDataFrame
和另一个函数otherFunction
(
做了一些实验,所以我用解决了我的问题(在Benjamin的建议下,并考虑到我添加到问题中的"编辑"(
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]) } )
通过这种方式,我注册了aGlobalDataFrame
、myfunction
和otherfunction
,简而言之,用于并行化作业的函数(myfunction
本身(使用的所有函数和数据
现在我没有在手机上看到这个,我可以看到一些问题。
首先,您实际上并没有在函数中创建otherDataFrame
。您正试图将现有的otherDataFrame
管道传输到filter
中,如果环境中不存在otherDataFrame
,则函数将失败。
其次,除非您已经将dplyr
包加载到集群环境中,否则您将调用错误的filter
函数。
最后,当您调用parApply
时,您没有在任何地方指定fst
和snd
应该是什么
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]") }