【发布时间】:2017-02-19 15:37:02
【问题描述】:
我有两个数据表:
library(data.table)
d1 <- data.table(grp = c("a", "c", "b", "a"), val = c(2, 3, 6, 7), y1 = 1:4, y2 = 5:8)
d2 <- data.table(grp = rep(c("a", "b", "c"), 2),
from = rep(c(1, 5), each = 3), to = rep(c(4, 10), each = 3), z = 11:16)
我执行非 equi 连接,其中 'd1' 中的值 'val' 应落在每个组 'grp' 的 'd2' 中的 'from' 和 'to' 定义的范围内。
d1[d2, on = .(grp, val >= from, val <= to), nomatch = 0]
# grp val y1 y2 val.1 z
# 1: a 1 1 5 4 11
# 2: c 1 2 6 4 13
# 3: a 5 4 8 10 14
# 4: b 5 3 7 10 15
在输出中,连接变量来自i('val' 和 'val.1',在 'd2' 中的值分别为 'from' 和 'to')。但是,我希望有x 的加入列。现在,因为...
x的列现在可以使用前缀x.来引用,并且在连接过程中特别有用,可以引用x的连接列,否则它们会被i屏蔽。
...这可以通过在j 中指定val = x.val 来实现:
d1[d2, .(grp, val = x.val, z), on = .(grp, val >= from, val <= to), nomatch = 0]
为了避免在j 中输入来自x 的所有非连接列(可能很多),我目前的解决方法是将上述内容与原始数据连接起来,从而得到所需的结果:
d1[d1[d2, .(grp, val = x.val, z), on = .(grp, val >= from, val <= to), nomatch = 0]
, on = .(grp, val)]
# grp val y1 y2 z
# 1: a 2 1 5 11
# 2: c 3 2 6 13
# 3: a 7 4 8 14
# 4: b 6 3 7 15
但是,这似乎有点笨拙。因此,我的问题是:如何一次性从x 中选择连接列以及j 中x 中的所有非连接列?
PS 我考虑过切换x 和i 数据集,以及on 中的条件。尽管这会产生所需的连接值,但它仍然需要后处理(删除、重命名和重新排序列)。
【问题讨论】:
-
我不知道后处理仅限于您拥有的许多非 equi cols...看起来还不错,例如
d2[d1, on=.(grp, from <= val, to >= val), nomatch=0][, `:=`(val = from, from = NULL, to = NULL)][] -
基于@docendo 的answer heremyabe 这个:
idx <- d2[d1, on = .(grp, from <= val, to >= val), which = TRUE]; d1[, z := d2$z[idx]][]? -
仅供参考,我在下面的答案中添加了@Jaap 评论的变体。
标签: r data.table