简体   繁体   English

在data.table中使用“!”运算符选择行时出错

[英]Error in selecting rows with “!” operator in data.table

I try to select rows using the ! 我尝试使用!选择行 operator 算子

d = data.table(a = 1:3, b = c(TRUE, FALSE,FALSE))

d [b==FALSE]
#    a     b
# 1: 2 FALSE
# 2: 3 FALSE


d [!b]
# Error in eval(expr, envir, enclos) : object 'b' not found

Shouldn't it be evaluated if it is an expression? 如果它是一个表达式,就不应该对其求值吗?

In data.table , when i is a symbol, it is evaluated in the calling scope (see ?data.table i argument explanation) and not within the frame of the data.table. data.table ,当i是符号时,它将在调用范围内进行评估(请参见idata.table i参数说明),而不是在data.table的框架内。 This is because we allow subsetting (or joining) data.tables using another data.table, ie, i can be another data.table. 这是因为我们允许使用另一个data.table子集(或联接)data.tables,即, i可以是另一个data.table。

require(data.table)
dt1 = data.table(x=1:3, y=4:6)
dt2 = data.table(x=2:3, z=7:8)

dt1[dt2, on="x"] # dt2 needs to be looked up first in the calling scope

Because of this feature, symbol in i needs to be wrapped with () so that it's seen as an expression (as opposed to a symbol), which is sufficient to understand that it needs to be evaluated within the frame of a data.table. 由于此功能, i 符号需要用()包裹,以便将其视为一个表达式(与符号相对),这足以理解它需要在data.table的框架内求值。 That is: 那是:

dt1[, id := c(TRUE, FALSE, TRUE)]
dt1[(id)] # rows 1 and 3

When you use !<symbol> , the "!" 当您使用!<symbol> ,“!” is caught and removed, and the rest of the expression is first evaluated and then "!" 被捕获并删除,然后首先对表达式的其余部分求值,然后再求“!” is introduced back.. (but done efficiently without materialising intermediate data), ie, 被引入回来..(但是有效地完成了但没有实现中间数据),即

dt1[!dt2, on="x"] 

computes the matching row indices by first computing the matching row indices for dt1[dt2, on="x"] and then obtaining the indices corresponding to "!" 通过首先计算dt1[dt2, on="x"]的匹配行索引,然后获取对应于“!”的索引,计算匹配行索引。 by taking the difference. 通过采取差异。

Therefore, we'll need a () when used with "!" 因此,当与“!”一起使用时,我们将需要一个() as well so that it's seen as an expression as opposed to a symbol. 以及将其视为与符号相对的一种表达方式。

dt1[!(id)] # works
dt1[(!id)] # also works

In general, this usage of subsetting a logical vector which is a column in the data.table is extremely rare compared to the usage and advantages of subsetting using another data.table. 通常,与使用另一个data.table进行子集设置的用法和优点相比,这种对data.table中的列作为逻辑向量进行子集设置的用法极为罕见。


This'll become a lot better when better scoping rules are implemented for i argument. 当为i参数实现更好的作用域规则时,这将变得更好。 See #633 . 参见#633

We need to put it inside brackets 我们需要把它放在方括号内

d [!(b)]
#   a     b
#1: 2 FALSE
#2: 3 FALSE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM