R data.table:笛卡尔连接和nomatch

R data.table:笛卡尔连接和nomatch,r,data.table,R,Data.table,我想使用R中难以置信的data.table包进行笛卡尔(完全外部)连接。但是,我也希望提到不匹配的行,即我的两个data.tables“left”和“right”看起来像 key | data_left 1 | aaa 2 | bbb 3 | ccc 及 带有键列“key”的交叉连接给了我 但是,完全缺少不匹配的行3 | ccc。添加选项nomatch=0(而不是nomatch=NA)没有帮助。我希望data.table用NA填充其余的列,所以我

我想使用R中难以置信的data.table包进行笛卡尔(完全外部)连接。但是,我也希望提到不匹配的行,即我的两个data.tables“left”和“right”看起来像

key | data_left
  1 |       aaa
  2 |       bbb
  3 |       ccc

带有键列“key”的交叉连接给了我

但是,完全缺少不匹配的行
3 | ccc
。添加选项
nomatch=0
(而不是
nomatch=NA
)没有帮助。我希望data.table用NA填充其余的列,所以我希望

key | data_left | data_right
  1 |       aaa |        xxx
  2 |       bbb |        yyy
  3 |       ccc |         NA
你知道我能做些什么才能让它发挥作用吗?

代码示例:

library(data.table)
left = data.table(keyCol = c(1,2,3), data_left = c("aaa", "bbb", "ccc"))
right = data.table(keyCol = c(1,2), data_right = c("xxx", "yyy"))
setkey(left, keyCol)
setkey(right, keyCol)
res0 = left[right, allow.cartesian=TRUE, nomatch=NA]
resNA = left[right, allow.cartesian=TRUE, nomatch=0]

假设每个
keyCol
值最多有一行,我会

# setup
kc = "keyCol"
DTs = list(left, right)

# make main table with key col(s)
DT = unique(rbindlist(lapply(DTs, `[`, j = ..kc)))

# get non-key cols
for (d in DTs){
  cols = setdiff(names(d), kc)
  DT[d, on=kc, (cols) := mget(sprintf("i.%s", cols)) ][]
}

# cleanup loop vars
rm(d, cols)
这应该适用于更一般的情况

  • 更多键列(在kc中)和
  • 更多具有非重叠列名称的表(在
    DTs
    中)

如果希望将key cols作为结果中的键,则代码会稍微简化:

# make main table with key col(s)
DT = setkey(unique(rbindlist(lapply(DTs, `[`, j = ..kc))))

# get non-key cols
for (d in DTs){
  cols = setdiff(names(d), kc)
  DT[d, (cols) := mget(sprintf("i.%s", cols)) ][]
}

这不管用吗
merge(左,右,by=“key”,all=T)
@Prem:这似乎可以完成任务,谢谢@HongOoi啊不?如果我理解正确的话,W3认为是:…哎呀,误读了代码样本。我几乎走了同一条路(检查两个键中有哪些键,然后在两个键上进行“内部-外部”连接,然后为不匹配的添加半个NA块)。这似乎是可行的,但我更喜欢Prem给出的解决方案,因为它更短,更“在”data.table包中…@FabianWerner Ok。顺便说一句,如果你确定
left
有所有的键,你可以做一个普通的左连接(如果我正确地使用了这个术语),通过引用添加:
left[right,data\u right:=I.data\u right]
# setup
kc = "keyCol"
DTs = list(left, right)

# make main table with key col(s)
DT = unique(rbindlist(lapply(DTs, `[`, j = ..kc)))

# get non-key cols
for (d in DTs){
  cols = setdiff(names(d), kc)
  DT[d, on=kc, (cols) := mget(sprintf("i.%s", cols)) ][]
}

# cleanup loop vars
rm(d, cols)
# make main table with key col(s)
DT = setkey(unique(rbindlist(lapply(DTs, `[`, j = ..kc))))

# get non-key cols
for (d in DTs){
  cols = setdiff(names(d), kc)
  DT[d, (cols) := mget(sprintf("i.%s", cols)) ][]
}