2016-01-06 130 views
1

我需要合并大型列表(aprox 15个数据帧[16000x6])。每个数据帧有2个id列"A""B"加上4列信息。将大型数据帧列表合并到一个数据帧中按列

我想要前两个("A""B"加上一个数据帧中的15 * 4列)。

我在另一个问题发现这一点:

Reduce(function(x,y) merge(x,y,by="your tag here"),your_list_here) 

然而,这,死机我的机器给这个错误,因为它需要太多RAM

In make.unique(as.character(rows)) : 
    Reached total allocation of 4060Mb: see help(memory.size) 
(仅使用3个DFS列表!)

我相信肯定会有更好的策略,我从dplyr包开始使用bind_cols,它让我真的快速复制A和B列的数据帧。也许删除这些列,保留前两个是更好的方法。

我提供你一个小玩具列表(减少(...)的策略在这里工作,但我需要另一种解决方案)

dput(mylist) 
structure(list(df1 = structure(list(A = c(1, 1, 2, 2, 3, 3), 
    B = c("Q", "Q", "Q", "P", "P", "P"), x1 = c(0.45840139570646, 
    0.0418491987511516, 0.798411589581519, 0.898478724062443, 
    0.064307059859857, 0.174364002654329), x2 = c(0.676136856665835, 
    0.494200984947383, 0.534940708894283, 0.220597118837759, 
    0.480761741055176, 0.0230771545320749)), .Names = c("A", 
"B", "x1", "x2"), row.names = c(NA, -6L), class = "data.frame"), 
    df2 = structure(list(A = c(1, 1, 2, 2, 3, 3), B = c("Q", 
    "Q", "Q", "P", "P", "P"), x1 = c(0.45840139570646, 0.0418491987511516, 
    0.798411589581519, 0.898478724062443, 0.064307059859857, 
    0.174364002654329), x2 = c(0.676136856665835, 0.494200984947383, 
    0.534940708894283, 0.220597118837759, 0.480761741055176, 
    0.0230771545320749)), .Names = c("A", "B", "x1", "x2"), row.names = c(NA, 
    -6L), class = "data.frame"), df3 = structure(list(A = c(1, 
    1, 2, 2, 3, 3), B = c("Q", "Q", "Q", "P", "P", "P"), x1 = c(0.45840139570646, 
    0.0418491987511516, 0.798411589581519, 0.898478724062443, 
    0.064307059859857, 0.174364002654329), x2 = c(0.676136856665835, 
    0.494200984947383, 0.534940708894283, 0.220597118837759, 
    0.480761741055176, 0.0230771545320749)), .Names = c("A", 
    "B", "x1", "x2"), row.names = c(NA, -6L), class = "data.frame")), .Names = c("df1", 
"df2", "df3")) 
+0

你能解释一点点/显示一些代码吗?我如何将15个dfs“存储”在一个循环中以便合并工作?我想到拆分和合并,但又一次,我需要“某处”来放置这些dfs –

+0

你期望重复键发生了什么?我怀疑这是什么炸毁你的电脑。 “1 Q”有两个条目,“3 P”有两个条目。你真的只是想要绑定这些数据集吗? – Zelazny7

+0

@ Zelazny7是的,我确定我想通过id列进行cbind +合并。记住我每DF有16000行,我宁愿有一个16000 * 62比一个巨大的高DF。此外,后来我有很多基于列的代码,许多函数会使用这些id colums并修改我不想再次编码的其他列。我最初做的是手动子集,但我现在需要做得更好。 –

回答

2

基于注释说明你要在16,000 X 62 data.frame。 ..

首先cbind非ID列:

tmp <- do.call(cbind, lapply(mylist, function(x) x[,-(1:2)])) 

然后加 “A” 和 “B”

final <- cbind(mylist[[1]][,1:2], tmp) 

没有需要合并,只是巴掌data.frames一起

> final 
    A B  df1.x1  df1.x2  df2.x1  df2.x2  df3.x1  df3.x2 
1 1 Q 0.45840140 0.67613686 0.45840140 0.67613686 0.45840140 0.67613686 
2 1 Q 0.04184920 0.49420098 0.04184920 0.49420098 0.04184920 0.49420098 
3 2 Q 0.79841159 0.53494071 0.79841159 0.53494071 0.79841159 0.53494071 
4 2 P 0.89847872 0.22059712 0.89847872 0.22059712 0.89847872 0.22059712 
5 3 P 0.06430706 0.48076174 0.06430706 0.48076174 0.06430706 0.48076174 
6 3 P 0.17436400 0.02307715 0.17436400 0.02307715 0.17436400 0.02307715 
+0

OP说每个data.frame有16,000行。如果存在重复的ID,Reduce/merge会在最终输出中产生一个包含16,000行以上的data.frame。 OP还在评论中指出,最终尺寸应该是16,000 x 62. – Zelazny7

3

对于cbind -ing的dataframes你可以这样做:

L <- mylist[[1]] 
for (i in 2:length(mylist)) L <- cbind(L, mylist[[i]][-(1:2)]) 

对于merge -ing(如所示前者(但是错误的)期望的输出为例):

L <- mylist[[1]] 
for (i in 2:length(mylist)) L <- merge(L, mylist[[i]], by=c("A", "B")) 

在情况为merge-我认为内存的需求来自数据帧之间的m:n连接。这不能通过合并的另一个过程来解决。

+0

我喜欢这种方法,如果“A”和“B”相等,我怀疑合并检查?如果不是,则会产生错误 –