我有一个我要合并的许多data.frames的列表.这里的问题是每个data.frame在行数和列数方面都不同,但它们都共享关键变量(我已经调用过"var1","var2"在下面的代码中).如果data.frames在列方面是相同的,我只能rbind,plyr的rbind.fill可以完成这项工作,但这些数据并非如此.
因为该merge命令仅适用于2个data.frames,所以我转向Internet寻求创意.我从这里得到了这个,它在R 2.7.2中完美运行,这是我当时所拥有的:
merge.rec <- function(.list, ...){
if(length(.list)==1) return(.list[[1]])
Recall(c(list(merge(.list[[1]], .list[[2]], ...)), .list[-(1:2)]), ...)
}
Run Code Online (Sandbox Code Playgroud)
我会像这样调用函数:
df <- merge.rec(my.list, by.x = c("var1", "var2"),
by.y = c("var1", "var2"), all = T, suffixes=c("", ""))
Run Code Online (Sandbox Code Playgroud)
但是在2.7.2之后的任何R版本中,包括2.11和2.12,此代码失败并出现以下错误:
Error in match.names(clabs, names(xi)) :
names do not match previous names
Run Code Online (Sandbox Code Playgroud)
(很明显,我在其他地方看到了其他对此错误的引用而没有解决方案).
有什么方法可以解决这个问题吗?
我即将合并大型数据集.这就是为什么我尝试使用data.table并且对它的速度感到激动.
# base R
system.time(
M1 <- Reduce(function(...) merge(..., all=TRUE), L)
)
# user system elapsed
# 5.05 0.00 5.20
# data.table
library(data.table)
L.dt <- lapply(L, function(x) setkeyv(data.table(x), c("sid", "id")))
system.time(
M2 <- Reduce(function(...) merge(..., all=TRUE), L.dt)
)
# user system elapsed
# 0.12 0.00 0.12
Run Code Online (Sandbox Code Playgroud)
两种方法都产生相同的值,但是有些列使用data.table进行拆分.
基地R:
set.seed(1)
car::some(M1, 5)
# sid id V3 V4 a b
# 60504 1 60504 -0.6964804 -1.210195 NA NA
# 79653 1 79653 -2.5287163 -1.087546 NA NA
# 111637 2 11637 0.7104236 NA …Run Code Online (Sandbox Code Playgroud) 我有一长串 data.tables。我想将它们全部合并(内连接)到一个 data.table 中。
与dplyr和purrr我可以做:
dt1 <- data.table(cbind(letters[1:10], 1:10))
dt2 <- data.table(cbind(letters[3:12], 3:12))
dt3 <- data.table(cbind(letters[5:15], 5:15))
dtl <- list(dt1, dt2, dt3)
library(dplyr)
library(purrr)
merged <- dtl %>% reduce(inner_join, by='V1')
Run Code Online (Sandbox Code Playgroud)
我怎样才能用 data.table 做到这一点?