我尝试使用!
运算符
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
如果是表达式,是否应该对它进行评估?
答案 0 :(得分:6)
在data.table
中,当i
是符号时,它将在调用范围内进行评估(请参阅?data.table i
参数说明),而不是在数据框内。表。这是因为我们允许使用另一个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
由于此功能,i
中的符号需要包含()
,以便将其视为表达式(与符号相对) ,这足以理解它需要在data.table的框架内进行评估。那就是:
dt1[, id := c(TRUE, FALSE, TRUE)]
dt1[(id)] # rows 1 and 3
当您使用!<symbol>
时,&#34;!&#34;捕获并删除,并首先评估表达式的其余部分然后&#34;!&#34;引入回来..(但有效地完成而没有实现中间数据),即
dt1[!dt2, on="x"]
通过首先计算dt1[dt2, on="x"]
的匹配行索引然后获得对应于&#34;!&#34;的索引来计算匹配的行索引。通过差异化。
因此,当与&#34;!&#34;一起使用时,我们需要()
。以及它被视为表达而不是符号。
dt1[!(id)] # works
dt1[(!id)] # also works
一般而言,与使用其他data.table进行子集化的使用和优势相比,使用对data.table中的列进行子集化逻辑向量的这种使用极为罕见。
当为i
参数实施更好的范围规则时,这将变得更好。请参阅#633。
答案 1 :(得分:1)
我们需要把它放在括号内
d [!(b)]
# a b
#1: 2 FALSE
#2: 3 FALSE