【问题标题】:unexpected behavior non-equi join data.table R [duplicate]意外行为非等连接data.table R [重复]
【发布时间】:2019-10-11 09:19:45
【问题描述】:

考虑一些样本数据

library(data.table)
dt1 <- data.table(foo = 1:4, bar = letters[1:4])
dt2 <- data.table(foo1 = 2:5, bar1 = LETTERS[1:4])

我正在尝试通过 non-equi 连接来连接这两个示例 data.tables(这也需要我设置笛卡尔连接选项):

options("datatable.allow.cartesian" = T)
dt3 <- dt1[dt2, on = .(foo < foo1), nomatch = 0L]

dt3 是:

    foo bar bar1
 1:   2   a    A
 2:   3   a    B
 3:   3   b    B
 4:   4   a    C
 5:   4   b    C
 6:   4   c    C
 7:   5   a    D
 8:   5   b    D
 9:   5   c    D
10:   5   d    D

但是这有两个问题:

  1. foo 没有值 5(这是一个明显的错误)
  2. foo1 不存在于输出中(这可能会限制进一步的条件;如果有的话)

为了绕过第二个条件,我试过了:

dt2[, foo11 := foo1]
dt4 <- dt1[dt2, on = .(foo < foo1), nomatch = 0L]
options("datatable.allow.cartesian" = F)

这给了我dt4

    foo bar bar1 foo11
 1:   2   a    A     2
 2:   3   a    B     3
 3:   3   b    B     3
 4:   4   a    C     4
 5:   4   b    C     4
 6:   4   c    C     4
 7:   5   a    D     5
 8:   5   b    D     5
 9:   5   c    D     5
10:   5   d    D     5

所以这里foo11 本质上是错误列foo 的副本,它看起来像另一个由于非等连接导致的错误。

我是否遗漏了任何一点或做错了什么?

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    我认为这种行为是预期的,除了变量的命名非常令人惊讶。我对您的示例数据进行了一些调整,以表明一切正常:

    dt1 <- data.table(foo = 1:4, bar = letters[1:4])
    dt2 <- data.table(foo1 = 2:4, bar1 = letters[2:4]) # small change here
    
    dt1[dt2, on = .(foo < foo1), allow.cartesian = TRUE][dt1, on = "bar"]
        foo bar bar1 i.foo
     1:   2   a    b     1
     2:   3   a    c     1
     3:   4   a    d     1
     4:   5   a    e     1
     5:   3   b    c     2
     6:   4   b    d     2
     7:   5   b    e     2
     8:   4   c    d     3
     9:   5   c    e     3
    10:   5   d    e     4
    

    对我来说,这种行为是预期的,只是第一列被命名为foo 而不是foo1。这就是为什么您将 fool1 视为“错误 foo: it's actually a copy offoo1` 的错误副本。

    编辑:一种可能的解决方法:

    这不是很优雅,但却是一种解决方法:

    dt1[dt2, .(foo = x.foo, foo1, bar, bar1), on = .(foo < foo1), allow.cartesian = TRUE]
        foo foo1 bar bar1
     1:   1    2   a    b
     2:   1    3   a    c
     3:   2    3   b    c
     4:   1    4   a    d
     5:   2    4   b    d
     6:   3    4   c    d
     7:   1    5   a    e
     8:   2    5   b    e
     9:   3    5   c    e
    10:   4    5   d    e
    

    x.foo 保留原来的,真实的foofoo1 仍然是原来的样子,所以你可以返回这两个变量。

    【讨论】:

    • 这个命名存在一个未解决的问题:github.com/Rdatatable/data.table/issues/3437。根据最新的发行说明和新闻,正在考虑对问题的反应以优先考虑解决方案,因此您可以考虑给它“赞”(原始问题的右上角)。
    • 非常感谢您的回答,因为它解除了对我的阻止。还指出了我会喜欢的问题(连同您的回答:))。我更喜欢您的编辑,因为它使用@Henrik 链接更简洁。对我的原始回答看起来更像是您再次加入表格的解决方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    • 2012-11-09
    • 1970-01-01
    • 2021-11-16
    • 2013-10-03
    • 1970-01-01
    • 2022-12-18
    相关资源
    最近更新 更多