我确定我忽略了显而易见的事情,但我找不到一种方法来连接 data.table
上“查找”表的所有列非平等加入 一步到位 .
我查看了 Arun 的演示文稿 (https://github.com/Rdatatable/data.table/wiki/talks/ArunSrinivasanSatRdaysBudapest2016.pdf) 和多个 SO 问题,但几乎所有这些问题都只涉及更新单个列,而不是加入多个列。
假设我有 2 个 data.tables a
和 b
:
library(data.table)
a <- data.table(Company_ID = c(1,1,1,1),
salary = c(2000, 3000, 4000, 5000))
# Company_ID salary
# 1: 1 2000
# 2: 1 3000
# 3: 1 4000
# 4: 1 5000
b <- data.table(cat = c(1,2),
LB = c(0, 3000),
UB = c(3000,5000),
rep = c("Bob","Alice"))
# cat LB UB rep
# 1: 1 0 3000 Bob
# 2: 2 3000 5000 Alice
我最终想要的是将 cat、LB、UB、rep(
b
中的所有列)与表 a
匹配:# Company_ID salary cat LB UB rep
# 1: 1 2000 1 0 3000 Bob
# 2: 1 3000 2 3000 5000 Alice
# 3: 1 4000 2 3000 5000 Alice
目前,我设法做到这一点的唯一方法是使用以下两行:
a <- a[b, on = .(salary >= LB, salary < UB), cat := cat]
a[b, on = .(cat == cat)]
它输出所需的表,但看起来很麻烦,一点也不像
data.table
方法。任何帮助将不胜感激!
最佳答案
由于您想要 a
的每一行的结果,你应该做一个类似 b[a, ...]
的连接:
b[a, on=.(LB <= salary, UB > salary), nomatch=0,
.(Company_ID, salary, cat, LB = x.LB, UB = x.UB, rep)]
Company_ID salary cat LB UB rep
1: 1 2000 1 0 3000 Bob
2: 1 3000 2 3000 5000 Alice
3: 1 4000 2 3000 5000 Alice
nomatch=0
意味着我们将删除 a
行在 b
中是无与伦比的. UB
和 LB
来自 b
的列使用 x.*
前缀(来自 ?data.table
文档,其中参数命名为 x[i]
)。 关于奇怪的默认列,有一个 Unresolved 问题可以改变该行为:#1615 .
( 第 1989 期,下面引用,现已修复 - 请参阅 Uwe 的回答。)
或者... 一种应该有效并避免显式列出所有列的方法:添加
a
的列到 b
,然后子集 b
:b[a, on=.(LB <= salary, UB > salary), names(a) := mget(paste0("i.", names(a)))]
b[b[a, on=.(LB <= salary, UB > salary), which=TRUE, nomatch=0]]
这有两个问题。首先,当遇到
mget
时,有一个 bug 会导致 non-equi join 中断。 ( #1989 )。临时解决方法是枚举 a
的列:b[a, on=.(LB <= salary, UB > salary), `:=`(Company_ID = i.Company_ID, salary = i.salary)]
b[b[a, on=.(LB <= salary, UB > salary), which=TRUE, nomatch=0]]
其次,执行此连接两次效率低下(一次用于
:=
,第二次用于 which
),但我看不到任何解决方法......也许可以证明功能请求允许 j
和 which
?
关于r - 非等连接一步添加 data.table 中范围表的所有列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41637736/