考虑一些示例数据
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
但是,这有两个问题:
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(那是一个明显的错误)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
的副本,由于非等价联接,它看起来像是另一个错误。
我在这里有什么遗漏之处吗?
答案 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
保留原始的真实foo
。 foo1
仍然如此,因此您可以返回两个变量。