问题 使用不等式和变量列名过滤data.table


我有一个 data.table 我想根据一些不平等标准进行过滤:

dt <- data.table(A=letters[1:3], B=2:4)
dt
#    A B
# 1: a 2
# 2: b 3
# 3: c 4

dt[B>2]
#    A B
# 1: b 3
# 2: c 4

以上情况适用于矢量扫描解决方案。但我无法弄清楚如何将它与列的变量名称结合起来:

mycol <- "B"
dt[mycol > 2]
#    A B      // Nothing has changed
# 1: a 2
# 2: b 3
# 3: c 4

我该如何解决这个问题?我知道我可以通过设置密钥使用二进制搜索 setkeyv(dt, mycol) 但是我看不出基于某些不等式标准进行二元搜索的方法。


1366
2017-12-13 14:46


起源

不 get(mycol) 工作? - Carl Witthoft
@CarlWitthoft是的。这将是我失踪的功能...... - MattLBeck
如果你愿意,你可以继续发布,作为答案。 - Carl Witthoft
这也有效 dt[eval(parse(text=mycol)) > 2] - digEmAll
@digEmAll的使用 eval(parse()) 是严格的verboten per fortune(106) - Carl Witthoft


答案:


好吧, 使用 get(mycol)  因为你想要参数 dt[ 成为对象“mycol”的内容。我相信 dt[mycol ...] 寻找一个“mycol”的东西 data.table 对象本身,其中当然没有这样的动物。


8
2017-12-13 16:48



这救了我。但即使你这样做 dt['B' > 2], 你必须做 dt[get('B') > 2]。有点讨厌/看起来像列引用应该作为一个字符串。 - wordsforthewise
@wordsforthewise感谢您的纠正。我不得不承认我在过去的4年里没有看过这个问题! - Carl Witthoft


为此提供了访问者功能。 j 在框架中评估 X,即你的 data.table除非 你指定 with = FALSE。这将是 典范 这样做的方式。

dt[ , mycol , with = FALSE ]
   B
1: 2
2: 3
3: 4

返回列,逻辑比较,子集行...

dt[ c( dt[ , mycol , with = FALSE ] > 2 ) ]

4
2017-12-13 17:10



@Mattrition看到更新。我不喜欢 get 因为在某些嵌套调用环境中可能会遇到一些意外行为。我会想到这一点 with = FALSE 将提供一个原因。 - Simon O'Hanlon
好的,您的答案现在提供了另一种替代解决方案,谢谢。我找到的第三种选择是 dt[dt[[mycol]] > 2]。 - MattLBeck
@Mattrition <捂脸> 这似乎是最明显的。你应该回答你自己的问题。 - Simon O'Hanlon
好吧,保持你的。 TMTOWTDI。 - MattLBeck
关于使用的好处 get 太。 - MattLBeck


另一种选择是使用 ]] 使用以下方法检索B作为向量和子集:

dt[dt[[mycol]] > 2]

4
2017-12-13 17:41