内部联接数据表,没有不需要的列

时间:2018-11-06 02:21:34

标签: r data.table

我有这两个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中选择列。我可以通过在加入后删除不需要的列来做到这一点,但我正在寻找一种在一个衬套中执行此操作的方法。任何帮助将不胜感激。

4 个答案:

答案 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)]

而不是引号“ z”