2013-04-18 125 views
0

本质上,我有一个大的数据框:10,000,000x900(行,列),我试图并行地转换每列的类。最终的结果必须是一个data.frameR并行大型数据帧转换

这里就是我有这么远:

假装df是已经定义的数据帧,所有列是数字和字符类的混合物

library(snow) 
cl=makeCluster(50,type="SOCK") 
cl.out=clusterApplyLB(cl,df,function(x)factor(x,exclude=NULL)) 

cl.out是我想要的,只是我需要的是这是一个data.frame类列表

所以这是我卡住...我要尝试,并结合所有的元素cl.out到data.frame w这不会是平行的吗? (SLOW,时间是个问题)

我可以使用不同的包来实现其他东西吗? (foreach?)

我必须硬编码一些c才能有效地完成这项工作吗?

任何帮助,将不胜感激。

感谢,

回答

0

由于data.frame是一个列表,用class属性, 你可以转换列表为data.frame, 与as.data.frame

cl.out <- as.data.frame(cl.out) 

我注意到,列名都将丢失:如果你确信他们是在同一顺序 ,您可以设置回用:

names(cl.out) <- names(df) 
+0

转换是相当缓慢的使用过程。我相信还有比简单地将类属性附加到数据blob上更多的东西。 –

+0

它不是很干净,但可以尝试直接更改属性: 'class(cl.out)< - “data.frame”'。 –

2

一个有用的范例是子集,更换所有列,治疗df如列表类似

df[] <- lapply(df, factor, exclude=NULL) 

你真的有一台机器上50个内核,如所暗示的您的来电makeCluster?如果你不是在Windows机器上,使用parallel包和mclapply代替

library(parallel) 
options(mc.cores=50) 
df[] <- mclapply(df, factor, exclude=NULL) 

,这真的会帮助你在你的总体评价?似乎要花费尽可能多的代价来分配和检索数据以进行计算。

> f = factor(rep("M", 10000000), levels=LETTERS) 
> df = data.frame(f, f, f, f, f, f, f, f) 
> system.time(lapply(df, factor, exclude=NULL)) 
    user system elapsed 
    2.676 0.564 3.250 
> system.time(clusterApply(cl, df, factor, exclude=NULL)) 
    user system elapsed 
    1.488 0.752 2.476 
> system.time(mclapply(df, factor, exclude=NULL)) 
    user system elapsed 
    1.876 1.832 1.814 

(多核和多进程计时可能高度可变)。

1

如果你有一个这样的大小的数据帧,我认为你会很快遇到内存问题非常

我认为它会更快,更高效。

你可以使用set

library(data.table) 

# to set as a data.table without having to copy 
setattr(df, 'class', c('data.table','data.frame') 
alloc.col(df) 

for(nn in names(df)){ 
    set(df, j = nn, value = factor(df[[nn]]) 
} 

值得一读data.table and parallel computing