【发布时间】:2014-12-15 20:50:25
【问题描述】:
我想在函数中使用plyr 包的并行功能。
我原以为导出已在函数体中创建的对象(在此示例中,对象为df_2)的正确方法如下
# rm(list=ls())
library(plyr)
library(doParallel)
workers=makeCluster(2)
registerDoParallel(workers,core=2)
plyr_test=function() {
df_1=data.frame(type=c("a","b"),x=1:2)
df_2=data.frame(type=c("a","b"),x=3:4)
#export df_2 via .paropts
ddply(df_1,"type",.parallel=TRUE,.paropts=list(.export="df_2"),.fun=function(y) {
merge(y,df_2,all=FALSE,by="type")
})
}
plyr_test()
stopCluster(workers)
但是,这会引发错误
Error in e$fun(obj, substitute(ex), parent.frame(), e$data) :
unable to find variable "df_2"
所以我做了一些研究,发现如果我手动导出df_2 就可以了
workers=makeCluster(2)
registerDoParallel(workers,core=2)
plyr_test_2=function() {
df_1=data.frame(type=c("a","b"),x=1:2)
df_2=data.frame(type=c("a","b"),x=3:4)
#manually export df_2
clusterExport(cl=workers,varlist=list("df_2"),envir=environment())
ddply(df_1,"type",.parallel=TRUE,.fun=function(y) {
merge(y,df_2,all=FALSE,by="type")
})
}
plyr_test_2()
stopCluster(workers)
它给出了正确的结果
type x.x x.y
1 a 1 3
2 b 2 4
但我也发现下面的代码有效
workers=makeCluster(2)
registerDoParallel(workers,core=2)
plyr_test_3=function() {
df_1=data.frame(type=c("a","b"),x=1:2)
df_2=data.frame(type=c("a","b"),x=3:4)
#no export at all!
ddply(df_1,"type",.parallel=TRUE,.fun=function(y) {
merge(y,df_2,all=FALSE,by="type")
})
}
plyr_test_3()
stopCluster(workers)
plyr_test_3() 也给出了正确的结果,我不明白为什么。我本来以为我必须导出df_2...
我的问题是:在函数内处理并行*ply 的正确方法是什么?显然,plyr_test() 是不正确的。我不知何故觉得plyr_test_2() 中的手动导出是没用的。但我也认为plyr_test_3() 是一种糟糕的编码风格。有人可以详细说明一下吗?谢谢大家!
【问题讨论】:
-
附带说明:由于您使用的是
ddply,您也可以尝试使用 dplyr,它是 plyr 的下一个版本对于数据帧,它可能会比ddply的并行化更快地提高您的代码性能。见Introduction to dplyr -
谢谢。不知道那个。
-
还有一个关于未来问题的注意事项:不要在您的问题中添加
rm(list=ls())未注释。其他人可能会在不注意的情况下运行代码,从而从他们的会话中删除重要数据。 -
:) 你是对的。对此感到抱歉。
-
我上面给出的代码只是一个最小的例子。实际上,我什至没有在我的脚本中使用
merge。
标签: r parallel-processing plyr