В пакете data.table
имеется специальный синтаксис, который требует использования выражений в качестве аргументов i
и j
.
Это имеет некоторые последствия для того, как одни функции записи принимают и передают аргументы таблицам данных, как это хорошо объясняется в разделе 1.16 часто задаваемых вопросов.
Но я не могу понять, как сделать этот дополнительный уровень.
Вот пример. Скажем, я хочу написать функцию-обертку foo()
, которая делает конкретное резюме моих данных, а затем вторую обертку plotfoo()
, которая вызывает foo()
и выводит результат:
library(data.table)
foo <- function(data, by){
by <- substitute(by)
data[, .N, by=list(eval(by))]
}
DT <- data.table(mtcars)
foo(DT, gear)
ОК, это работает, потому что я получаю результаты с табулированием:
by N
1: 4 12
2: 3 15
3: 5 5
Теперь я пытаюсь сделать то же самое при написании plotfoo()
, но я терплю неудачу:
plotfoo <- function(data, by){
by <- substitute(by)
foo(data, eval(by))
}
plotfoo(DT, gear)
Но на этот раз я получаю сообщение об ошибке:
Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
ОК, поэтому проблема eval()
. Удалите его:
plotfoo <- function(data, by){
by <- substitute(by)
foo(data, by)
}
plotfoo(DT, gear)
Нет, я получаю новое сообщение об ошибке:
Error in `[.data.table`(data, , .N, by = list(eval(by))) :
column or expression 1 of 'by' or 'keyby' is type symbol. Do not quote column names. Useage: DT[,sum(colC),by=list(colA,month(colB))]
И здесь я остаюсь застрявшим.
Вопрос: Как написать функцию, вызывающую функцию, которая вызывает data.table?