R data.table:笛卡尔连接和nomatch
我想使用R中难以置信的data.table包进行笛卡尔(完全外部)连接。但是,我也希望提到不匹配的行,即我的两个data.tables“left”和“right”看起来像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填充其余的列,所以我
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)) ][]
}