Как функция J() реализована в data.table?

Недавно я узнал об элегантном R-пакете data.table. Мне очень любопытно узнать, как там реализована функция J. Эта функция привязана к функции [.data.table, она не существует в глобальной среде.

Я загрузил исходный код, но я не могу найти определение для этой функции J где угодно. Я нашел lockBind(".SD", ...), но не J. Любая идея, как эта функция реализована?

Большое спасибо.

Ответ 1

J() раньше экспортировался, но не с 1.8.8. Здесь примечание от 1.8.8:

o Алиас J() теперь удален за пределами DT[...], но все равно будет работать внутри DT[...]; т.е. DT[J(...)] является прекрасным. Как предупреждено в v1.8.2 (см. Ниже в этом файле) и устарел с warning() в v1.8.4. Это разрешает конфликт с функцией J() в пакете XLConnect (# 1747) и rJava (# 2045). Используйте data.table() непосредственно вместо J(), вне DT[...].

Используя оценку R lazy, J(.) обнаруживается и просто заменяется на list(.) с использованием (невидимой) неэкспортируемой функции .massagei.

То есть, когда вы делаете:

require(data.table)
DT = data.table(x=rep(1:5, each=2L), y=1:10, key="x")
DT[J(1L)]

i (= J(1L)) проверяется для своего типа, и эта строка выполняется:

i = eval(.massagei(isub), x, parent.frame())

где isub = substitute(i) и .massagei просто:

.massagei = function(x) {
    if (is.call(x) && as.character(x[[1L]]) %chin% c("J","."))
        x[[1L]] = quote(list)
    x
}

В основном выполняется data.table:::.massagei(quote(J(1L))), который возвращает list(1L), который затем преобразуется в data.table. И оттуда ясно, что должен произойти a join.