意外行为非等价联接数据表R

时间:2019-10-11 09:19:45

标签: r data.table

考虑一些示例数据

List<? super Object>

我正在尝试通过非等距联接来联接这两个示例数据表(这也需要我设置笛卡尔联接选项):

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

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

dt3

但是,这有两个问题:

  1. 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 列没有值5(那是一个明显的错误)
  2. 在输出中不存在
  3. foo(可能会限制进一步的条件;如果有的话)

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

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的副本,由于非等价联接,它看起来像是另一个错误。

我在这里有什么遗漏之处吗?

1 个答案:

答案 0 :(得分:2)

我认为行为是预期的,除了变量被意外地命名。我对您的示例数据做了一些调整,以表明一切正常:

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 of foo1`的错误副本。

编辑:可能的解决方法:

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

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仍然如此,因此您可以返回两个变量。