ОБНОВЛЕНИЕ (Eddi): По состоянию version 1.8.11 это было исправлено и .SD
не требуется в тех случаях, когда выражение может быть вычислено на месте, как и в ОП. Поскольку в настоящее время наличие .SD
приводит к созданию полного .SD
, это приведет к значительно более высокой скорости в некоторых случаях.
Что происходит в том, что призывы к eval()
обращаются иначе, чем вы, вероятно, представить себе в коде, который реализует [.data.table()
. В частности, [.data.table()
содержит специальные ветви оценки для i
и j
выражения, которые начинаются с символа eval
. Когда вы завершаете вызов eval
внутри вызова sum()
, eval
уже не является первым элементом анализируемого/замещенного выражения, а специальная ветвь оценки пропускается.
Вот немного кода в функции монстра отображается набрав getAnywhere("[.data.table")
, что делает специальное пособие для звонков в eval()
передали через [.data.table()
«s j
-argument:
jsub = substitute(j)
...
# Skipping some lines
...
jsubl = as.list.default(jsub)
if (identical(jsubl[[1L]], quote(eval))) { # The test for eval 'on the outside'
jsub = eval(jsubl[[2L]], parent.frame(), parent.frame())
if (is.expression(jsub))
jsub = jsub[[1L]]
}
В качестве временного решения, либо следовать пример в data.table FAQ 1.6 (pdf here), или явно указать eval()
в сторону .SD
, локальную переменную, которая содержит столбцы любой таблицы данных, на которой вы работаете (здесь d
). (Для более подробного объяснения роли .SD
см. Первые несколько параграфов this answer).
d[, sum(eval(quoted_a, envir=.SD))]
У меня была такая проблема сегодня; была решена с помощью 'quote (sum (a))' вместо 'expression (sum (a))'. Не знаю, почему это имело значение. – rbatt