r - 非等连接一步添加 data.table 中范围表的所有列

标签 r join data.table

我确定我忽略了显而易见的事情,但我找不到一种方法来连接 data.table 上“查找”表的所有列非平等加入 一步到位 .

我查看了 Arun 的演示文稿 (https://github.com/Rdatatable/data.table/wiki/talks/ArunSrinivasanSatRdaysBudapest2016.pdf) 和多个 SO 问题,但几乎所有这些问题都只涉及更新单个列,而不是加入多个列。

假设我有 2 个 data.tables ab :

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 中是无与伦比的.
  • 我们需要明确引用 UBLB来自 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 ),但我看不到任何解决方法......也许可以证明功能请求允许 jwhich ?

    关于r - 非等连接一步添加 data.table 中范围表的所有列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41637736/

    相关文章:

    r - 按组对大于当前值的值求和

    r - R中直方图中条形的中心值

    r - 如何滚动应用多列数据表

    R: 系统找不到指定的文件?

    r - 在三方 igraph 上的层内排序顶点

    mysql - 我如何从表中的两个查询中获取公共(public)值并将其与 MySql 中的另一个表连接?

    r - 如何调用 data.table 的基于列的子集而不自动对行进行排序?

    r - data.table:如何将字符向量传递给函数 get data.table 以将其内容视为列名?

    mysql - sql group by 不显示所有结果

    MySql , JOIN 和 Group By 查询正在使用临时和 Filesort