首先我要说的是,这是我在堆栈溢出时发布的第一个问题。如果我需要在我的问题中更改样式,格式等,请告诉我。
我想对两个数据表执行左外连接操作,其中一个exra条件允许我对两个数据表中的关键变量使用不同的名称。例如:
DT1 = data.table(x1=c("b","c", "a", "b", "a", "b"), x2a=1:6,m1=seq(10,60,by=10))
setkey(DT1,x1,x2a)
> DT1
x1 x2a m1
1: a 3 30
2: a 5 50
3: b 1 10
4: b 4 40
5: b 6 60
6: c 2 20
DT2 = data.table(x1=c("b","d", "c", "b","a","a"),x2b=c(1,4,7,6," "," "),m2=5:10)
setkey(DT2,x1,x2b)
> DT2
x1 x2b m2
1: a 9
2: a 10
3: b 1 5
4: b 6 8
5: c 7 7
6: d 4 6
############# first, I use the merge operation on the data frames to do a left outer join
dfL<-merge.data.frame(DT1,DT2,by.x=c('x1','x2a'),by.y=c('x1','x2b'),all.x=TRUE)
> dfL
x1 x2a m1 m2
1 a 3 30 NA
2 a 5 50 NA
3 b 1 10 5
4 b 4 40 NA
5 b 6 60 8
6 c 2 20 NA
################# attempt with data table left outer join
> dtL<-DT2[DT1,on=c("x1","x2a")]
Error in forderv(x, by = rightcols) :
'by' value -2147483648 out of range [1,3]
#################### code that works with data table
DT1 = data.table(x1=c("b","c", "a", "b", "a", "b"), x2=as.character(1:6),m1=seq(10,60,by=10))
setkey(DT1,x1,x2)
DT1
DT2 = data.table(x1=c("b","d", "c", "b","a","a"),x2=c(1,4,7,6," "," ") ,m2=5:10)
setkey(DT2,x1,x2)
DT2
dtL<-DT2[DT1]
######################## this required identical naming of the key variables in the two data tables
################### Also does not allow a ad-hoc selection of the key variables with the "on" argument
我想知道是否可以保留合并命令与数据帧的灵活性。使用data.table。
答案 0 :(得分:7)
从v1.9.6(2015年9月CRAN):
X[Y]
语法现在可以加入而无需设置键 使用新的on
参数。例如:DT1[DT2, on=c(x = "y")]
会 将DT2
的“y”列与DT1
的“x”相连接。DT1[DT2, on="y"]
将加入两个data.tables的列“y”。
请在README中搜索字符串“on =”,以获取有关开发中v1.9.7中on=
的更多相关项目。您要求左外连接,这是默认的X[Y]
语法(X[Y,nomatch=0]
切换到内连接)。
但请注意,如果您可以支付setkey
的前期费用(在data.table中相当快),那么设置密钥总是会更快以便随后加入。该概念类似于SQL中的 clustered 索引。
X[Y]
语法与merge()
的优势在于您可以在同一j
个查询中包含by
和[...]
。这样的查询已经过优化,只有j
表达式所需的列才会加入,从而节省了时间和RAM。见FAQ 1.12。 by=.EACHI
也是X[Y]
语法的一个强大功能,您无需使用merge()
并且目前对data.table是唯一的。您可以在on=
查询中使用by=.EACHI
和DT[...]
。
答案 1 :(得分:2)
来自?data.table::merge
data.table的这种合并方法与data.frames的合并方法非常相似,但有一个主要的例外:默认情况下,用于合并data.tables的列是共享键列,而不是具有相同名称的共享列。明确地设置by或byx,by.y参数以覆盖此默认值。
因此我们可以使用by
参数来覆盖keys
。
library(data.table)
DT1 = data.table(x1=c("b","c", "a", "b", "a", "b"), x2a=1:6,m1=seq(10,60,by=10))
DT2 = data.table(x1=c("b","d", "c", "b","a","a"),x2b=c(1,4,7,6," "," "),m2=5:10)
## you will get an error when joining a character to a integer:
DT2$x2b <- as.integer(DT2$x2b)
## Alternative:
## DT2 = data.table(x1=c("b","d", "c", "b","a","a"),x2b=c(1,4,7,6,NA,NA),m2=5:10)
merge(DT1, DT2, by.x=c('x1','x2a'), by.y=c('x1','x2b'), all.x=TRUE)
x1 x2a m1 m2
1: a 3 30 NA
2: a 5 50 NA
3: b 1 10 5
4: b 4 40 NA
5: b 6 60 8
6: c 2 20 NA