如何在data.table中连接具有OR条件的表

时间:2017-03-14 14:25:26

标签: r join merge data.table

在data.table中是否可以连接具有OR条件的表?

例如:

library(data.table)
X<-data.table(x=c('a','b','c','d','e','f'),y=c(1,1,2,2,3,3),z=c(10,11,12,13,14,15))
   x y  z
1: a 1 12
2: b 1 11
3: c 2 12
4: d 2 13
5: e 3 14
6: f 3 15  

Y<-data.table(x=c('a','e','a'),z=c(12,20,14),t=c('a','b','c'))
   x  z t
1: a 12 a
2: e 20 b
3: a 14 c

# and i need something like this:
X[Y,on=c("x"|"z"),.(x,y,z,i.t)]
   x y  z t
1: a 1 10 a
2: a 1 10 c
3: b 1 11 NA
4: c 2 12 a
5: d 2 13 NA
6: e 3 14 b
7: e 3 14 c
8: f 3 15 NA

我没有找到有关在文档中加入OR的信息。 我错过了什么吗?

2 个答案:

答案 0 :(得分:4)

OP要求结果集应包含3个子集:

  1. 匹配列x
  2. 的行
  3. 匹配列y
  4. 的行
  5. 其余的data.table X
  6. 因此,这是表XYxy之间的一种右外连接。

    这可以转换为列xy上的2个单独的内部联接,两个结果集的联合,以及用于添加表{{1}中的其余行的最终外部联接}}

    在一个X语句中合并后,这就变成了

    data.table

    内部联接由参数unique(rbindlist(list( X[Y, on = "x", .(x, y, z, t), nomatch = 0], X[Y, on = "z", .(x, y, z, t), nomatch = 0] )))[X, on = .(x, y, z)] # x y z t #1: a 1 10 a #2: a 1 10 c #3: b 1 11 NA #4: c 2 12 a #5: d 2 13 NA #6: e 3 14 b #7: e 3 14 c #8: f 3 15 NA 强制执行。联合操作使用nomatch = 0实现。如果rbindlist(list(...))unique()x和{{{}中的同一行匹配,则编辑 z需要删除双重匹配1}}(thanks to filius_arator for pointing this out)。

    最后的右外连接使用X的所有行,包括那些尚未匹配的行。请注意,此联接位于Y的三列。

答案 1 :(得分:1)

我不确定这是否是你想要的,或者它是非常data.table-esque但是目前还没有其他答案:

join1 <- merge(X, Y[,c('x', 't'), with=FALSE], all.x=TRUE)
merge(join1, Y[,c('z', 't'), with=FALSE], all.x=TRUE, by = 'z')[, 
    t := ifelse(!is.na(t.x), t.x, t.y)][,
    t.x := NULL][,
    t.y := NULL][]

,并提供:

    z x y  t
1: 10 a 1  a
2: 11 b 1 NA
3: 12 c 2  a
4: 13 d 2 NA
5: 14 e 3  b
6: 15 f 3 NA

编辑这里有更新的示例,这是一种方法,但我确信data.table大师应该有更好的方法:

join1 <- merge(X, Y[,c('x', 't'), with=FALSE], all.x=TRUE)
merge(join1, Y[,c('z', 't'), with=FALSE], all.x=TRUE, by = 'z')[,
    id := seq(.N)][, 
    .(t =list( na.omit(c(t.x, t.y)))), by = c('id', 'x', 'y', 'z')][,
    .(x=x, y=y, z=z, t=unlist(t)), by = c('id')][]

##    id x y  z  t
## 1:  1 a 1 10  a
## 2:  2 a 1 10  c
## 3:  3 b 1 11 NA
## 4:  4 c 2 12  a
## 5:  5 d 2 13 NA
## 6:  6 e 3 14  b
## 7:  6 e 3 14  c
## 8:  7 f 3 15 NA