繁体   English   中英

有效地加入2个以上的data.tables

[英]Efficiently joining more than 2 data.tables

我想知道是否有一种内存有效的方式来加入n data.tables(或数据帧)。 例如,如果我有以下4个data.tables:

df1 = data.table(group = c(1L,2L,3L),value = rnorm(3),key = "group")
df2 = data.table(group = c(2L,1L,3L),value2 = rnorm(3),key = "group")
df3 = data.table(group = c(3L,2L,1L),value3 = rnorm(3),key = "group")
df4 = data.table(group = c(1L,3L,2L),value4 = rnorm(3),key = "group")

我可以像这样合并它们:

merge(df1,merge(df2,merge(df3,df4)))

但这似乎不是一个最佳解决方案。 我可能有许多需要合并的data.tables。 有没有办法概括上述内容而不将每个连续的合并复制到内存? 在data.table之外是否有一种已经被接受的方法可以做到这一点?

根据您的数据,以下是您可能拥有的其他一些选项。 除了显而易见的大量合并之外的其他选择,我的意思是:在一个循环中,使用Reduce或者使用hadley的join_all / merge_all / wrap_em_all_up

这些都是我使用的方法,并且发现在我自己的工作中更快,但我不打算尝试一般的基准测试案例。 首先,一些设置:

DFlist = list(df1,df2,df3,df4)
bycols = key(DFlist[[1]])

我假设这些表都是由bycols键入的。

堆。 如果每个表中的新cols以某种方式彼此相关并且出现在每个表中的相同位置,那么考虑只是堆叠数据:

DFlong = rbindlist(DFlist, use.names = FALSE, idcol = TRUE)

如果由于某种原因你真的想要宽格式的数据,你可以dcast

dcast(DFlong, 
  formula = sprintf("%s ~ .id", paste(bycols, collapse = "+")), 
  value.var = setdiff(names(DFlong), c(bycols, ".id"))
)

但是,Data.table和R最适合使用长格式数据。

复制cols。 如果您知道bycols在所有表中采用所有相同的值,那么只需复制:

DF = DFlist[[1]][, bycols, with=FALSE]
for (k in seq_along(DFlist)){
  newcols = setdiff(names(DFlist[[k]]), bycols)
  DF[, (newcols) := DFlist[[k]][, newcols, with=FALSE]]
}

合并分配。 如果某些表中可能缺少某些级别的bycols ,则创建包含所有组合的主表并执行一系列merge-assigns:

DF = unique(rbindlist(lapply(DFlist, `[`, j = bycols, with = FALSE)))
for (k in seq_along(DFlist)){
  newcols = setdiff(names(DFlist[[k]]), bycols)
  DF[DFlist[[k]], (newcols) := mget(newcols)]
}

在dplyr中:

由于您的试验都具有相同的名称(并且您已经清除了NA),您可以绑定行并进行汇总。

library(dplyr)

DF <- bind_rows(df1,df2,df3,df4) %>%
    group_by(group) %>%
    summarise_each(funs(na.omit))

除此之外,还有一个简单的局部最小解决方案:尽管至少用这种方言编码可以节省你自己洋葱的几层。

DF <- 
    df1 %>% 
    full_join(df2) %>% 
    full_join(df3) %>% 
    full_join(df4) 

由于dplyr在C ++中运行而不是S,它应该更快。 遗憾的是,我无法说出内存使用效率。

(对于类似的情况,请参阅: R:用另一个数据帧的dplyr sol'n 更新数据帧

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM