Data.table подмножество строк с использованием логического столбца: почему я должен явно сравнивать с TRUE?

Мне интересно, почему для данных data.table:

library(data.table)
DT <- structure(list(number = 1:5, bmask = c(FALSE, TRUE, FALSE, TRUE, 
FALSE)), .Names = c("number", "bmask"), row.names = c(NA, -5L
), class = c("data.table", "data.frame"))

> DT
   number bmask
1:      1 FALSE
2:      2  TRUE
3:      3 FALSE
4:      4  TRUE
5:      5 FALSE

выражение DT[bmask==T,.(out=number)] работает так, как ожидалось:

   out
1:   2
2:   4

но DT[bmask,.(out=number)] вызывает ошибку:

> DT[bmask,.(out=number)]
Error in eval(expr, envir, enclos) : object 'bmask' not found

Это правильное поведение пакета data.table?

Ответ 1

Используйте это вместо:

DT[(bmask), .(out=number)]
#    out
# 1:   2
# 2:   4

Роль скобок заключается в том, чтобы помещать символ bmask внутри вызова функции, из среды оценки которого столбцы DT будут видны 1. Любой другой вызов функции, который просто возвращает значение bmask (например, c(bmask), I(bmask) или bmask==TRUE) или индексы его истинных элементов (например, which(bmask)), будет работать так же хорошо, но может занять немного больше времени вычислить.

Если bmask не находится внутри вызова функции, он будет искать в области вызова (здесь глобальная среда), что также может быть полезно иногда. Здесь соответствующее объяснение от ?data.table:

Дополнительно: когда "i" - это одно имя переменной, это не считается выражением имен столбцов и вместо этого оценивается в области вызова.


1 Чтобы увидеть, что () сам является вызовом функции, введите is(`(`).