我想知道是否有一种内存有效的方式来加入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之外是否有一种已经被接受的方法可以做到这一点?
答案 0 :(得分:5)
根据您的数据,以下是您可能拥有的其他一些选项。其他选项除了进行大量合并的明显路径之外,我的意思是:在循环中,使用Reduce
或使用hadley' join_all
/ merge_all
/ {{1} }。
这些都是我使用的方法,并且发现在我自己的工作中更快,但我并不打算尝试一般的基准测试案例。首先,一些设置:
wrap_em_all_up
我假设这些表都由DFlist = list(df1,df2,df3,df4)
bycols = key(DFlist[[1]])
键入。
Stack。如果每个表中的新cols以某种方式相互关联并出现在每个表中的相同位置,那么请考虑只堆叠数据:
bycols
如果由于某种原因你真的想要宽格式的数据,你可以DFlong = rbindlist(DFlist, use.names = FALSE, idcol = TRUE)
:
dcast
尽管如此,Data.table和R最适合使用长格式数据。
复制cols。如果您知道dcast(DFlong,
formula = sprintf("%s ~ .id", paste(bycols, collapse = "+")),
value.var = setdiff(names(DFlong), c(bycols, ".id"))
)
在所有表中都采用了所有相同的值,那么只需复制:
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
答案 1 :(得分:0)
在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: Updating a data frame with another data frame's dplyr sol'n)