我正在尝试使用data.table
对作为列表元素存储的多个数据帧进行完全外连接。我已经使用merge_recurse()
包的reshape
函数成功完成了这项工作,但是对于更大的数据集来说它非常慢,我想通过使用data.table来加速合并。我不确定data.table处理具有多个数据帧的列表结构的最佳方法。我也不确定我是否在唯一键上正确编写了Reduce()
函数,以便在多个数据帧上进行完全外连接。
这是一个小例子:
#Libraries
library("reshape")
library("data.table")
#Specify list of multiple dataframes
filelist <- list(data.frame(x=c(1,1,1,2,2,2,3,3,3), y=c(1,2,3,1,2,3,1,2,3), a=1:9),
data.frame(x=c(1,1,1,2,2,2,3,3,4), y=c(1,2,3,1,2,3,1,2,1), b=seq(from=0, by=5, length.out=9)),
data.frame(x=c(1,1,1,2,2,2,3,3,4), y=c(1,2,3,1,2,3,1,2,2), c=seq(from=0, by=10, length.out=9)))
#Merge with merge_recurse()
listMerged <- merge_recurse(filelist, by=c("x","y"))
#Attempt with data.table
ids <- lapply(filelist, function(x) x[,c("x","y")])
unique_keys <- unique(do.call("rbind", ids))
dt <- data.table(filelist)
setkey(dt, c("x","y")) #error here
Reduce(function(x, y) x[y[J(unique_keys)]], filelist)
这是我的预期输出:
> listMerged
x y a b c
1 1 1 1 0 0
2 1 2 2 5 10
3 1 3 3 10 20
4 2 1 4 15 30
5 2 2 5 20 40
6 2 3 6 25 50
7 3 1 7 30 60
8 3 2 8 35 70
9 3 3 9 NA NA
10 4 1 NA 40 NA
11 4 2 NA NA 80
以下是我的资源:
答案 0 :(得分:3)
这对我有用:
library("reshape")
library("data.table")
##
filelist <- list(
data.frame(
x=c(1,1,1,2,2,2,3,3,3),
y=c(1,2,3,1,2,3,1,2,3),
a=1:9),
data.frame(
x=c(1,1,1,2,2,2,3,3,4),
y=c(1,2,3,1,2,3,1,2,1),
b=seq(from=0, by=5, length.out=9)),
data.frame(
x=c(1,1,1,2,2,2,3,3,4),
y=c(1,2,3,1,2,3,1,2,2),
c=seq(from=0, by=10, length.out=9)))
##
## I used copy so that this would
## not modify 'filelist'
dtList <- copy(filelist)
lapply(dtList,setDT)
lapply(dtList,function(x){
setkeyv(x,cols=c("x","y"))
})
##
> Reduce(function(x,y){
merge(x,y,all=T,allow.cartesian=T)
},dtList)
x y a b c
1: 1 1 1 0 0
2: 1 2 2 5 10
3: 1 3 3 10 20
4: 2 1 4 15 30
5: 2 2 5 20 40
6: 2 3 6 25 50
7: 3 1 7 30 60
8: 3 2 8 35 70
9: 3 3 9 NA NA
10: 4 1 NA 40 NA
11: 4 2 NA NA 80
此外,我注意到您的代码中存在一些问题。 dt <- data.table(filelist)
导致了
> dt
filelist
1: <data.frame>
2: <data.frame>
3: <data.frame>
这很可能是您在上面指出的setkey(dt, c("x","y"))
错误的原因。还有,这对你有用吗?
Reduce(function(x, y) x[y[J(unique_keys)]], filelist)
我只是好奇,因为我在尝试运行时遇到错误(使用dtList
代替filelist
)
Error in eval(expr, envir, enclos) : could not find function "J"
我认为这与data.table
版本1.8.8以来实施的更改有关,由@Arun在this answer解释。