使用“!”选择行时出错data.table

时间:2016-07-11 10:26:46

标签: r data.table

我尝试使用!运算符

选择行
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

如果是表达式,是否应该对它进行评估?

2 个答案:

答案 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