r - 意外行为非等连接data.table R
问题描述
考虑一些样本数据
library(data.table)
dt1 <- data.table(foo = 1:4, bar = letters[1:4])
dt2 <- data.table(foo1 = 2:5, bar1 = LETTERS[1:4])
我正在尝试通过非等连接加入这两个示例 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
但是,这样做有两个问题:
- 列
foo
没有值 5(这是一个明显的错误) - 列
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
它看起来像另一个由于非 equi 连接而导致的错误。
我在这里错过任何一点或做错了吗?
解决方案
我认为这种行为是预期的,除了变量的命名非常令人惊讶。我对您的示例数据进行了一些调整,以表明一切正常:
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
仍然是它的样子,所以你可以返回两个变量。
推荐阅读
- android - 如何在 google play 控制台中重新提交游戏?
- javascript - 如何将项目符号添加到 div 标题?
- ios - 使用 CNContacts (Swift) 实现搜索控制器的问题
- haskell - 如何在 Haskell 中一起写整数和字符串?
- c# - 如何在 C# 中获取安装项目的自定义操作数据?
- python - 我怎样才能让我的模型以 2 个张量作为输入。我曾尝试使用合并层,但我并没有完全让它工作
- javascript - 如何在 i18n-js 中使用 setLocale?
- asp.net - ASP.NET 无法自动对用户进行身份验证
- android - 保存 ArCore 会话并再次查看它,即使不在同一位置也是如此
- php - PHP - LightHouse - ID 标量大小不够