我有这两个DT,我想执行内部联接;
DT1:
x y v foo
1: A A1 1 1
2: B A1 2 1
3: C A1 3 1
4: D A2 4 1
5: E A2 5 2
6: F A2 6 1
7: G A3 7 2
8: H A3 8 0
9: I A3 9 0
DT2:
x z
1: A 1
2: B 2
3: C 3
4: D 4
5: E 5
6: F 6
这两个由DT[DT2, nomatch=0L, on="x"]
组成的内部连接将为:
x y v foo z
1: A A1 1 1 1
3: C A1 3 1 3
4: D A2 4 1 4
5: E A2 5 2 5
6: F A2 6 1 6
我要生成的内容如下:
x y v z
1: A A1 1 1
2: B A1 2 2
3: C A1 3 3
4: D A2 4 4
5: E A2 5 5
6: F A2 6 6
如您所见,我想联接两个DT,从其中一个联接的DT中选择列。我可以通过在加入后删除不需要的列来做到这一点,但我正在寻找一种在一个衬套中执行此操作的方法。任何帮助将不胜感激。
答案 0 :(得分:3)
一种选择是使用sqldf
包并进行数据库样式连接:
sql <- "SELECT t2.x, t1.y, t1.v, t2.z
FROM DT2 t2
LEFT JOIN DT1 t1
ON t2.x = t1.x"
result <- sqldf(sql)
在此处使用sqldf
的一个优点是,它可以轻松地选择结果中所需的列以及顺序。
答案 1 :(得分:2)
由于结果表与DT2具有相同的行,因此可以在其中添加它们:
cols = c("y", "v")
DT2[, (cols) := DT1[DT2, on="x", ..cols]]
x z y v
1: A 1 A1 1
2: B 2 A1 2
3: C 3 A1 3
4: D 4 A2 4
5: E 5 A2 5
6: F 6 A2 6
这会发出警告,但有a bug report的相关警告。
您可能还会对此问题感兴趣:Perform a semi-join with data.table
答案 2 :(得分:1)
这不是data.table解决方案,但是使用我的软件包safejoin
中的eat
确实很简单:
# devtools::install_github("moodymudskipper/safejoin")
library(safejoin)
eat(DT2, DT1, -foo)
# x z y v
# 1 A 1 A1 1
# 2 B 2 A1 2
# 3 C 3 A1 3
# 4 D 4 A2 4
# 5 E 5 A2 5
# 6 F 6 A2 6
数据
DT1 <- read.table(header=TRUE,stringsAsFactors=FALSE,text="x y v foo
A A1 1 1
B A1 2 1
C A1 3 1
D A2 4 1
E A2 5 2
F A2 6 1
G A3 7 2
H A3 8 0
I A3 9 0")
DT2 <- read.table(header=TRUE,stringsAsFactors=FALSE,text="x z
A 1
B 2
C 3
D 4
E 5
F 6")
答案 3 :(得分:1)
这使您相当接近。第一步是对DT1中x在DT2[["x"]]
中的行进行逻辑选择,然后绑定z值:
cbind( DT1[x %in% DT2[,x] ], DT2[ , z] )
x y v foo V2
1: A A1 1 1 1
2: B A1 2 1 2
3: C A1 3 1 3
4: D A2 4 1 4
5: E A2 5 2 5
6: F A2 6 1 6
如果您在第二个data.table中引用j
参数,而忽略了foo
,则为确切答案:
cbind( DT1[x %in% DT2[,x], list(x,y,v)], DT2[ , "z"] )
#-------------------
x y v z
1: A A1 1 1
2: B A1 2 2
3: C A1 3 3
4: D A2 4 4
5: E A2 5 5
6: F A2 6 6
您本可以使用DT2[ , list(z)]