The package data.table
has some special syntax that requires one to use expressions as the i
and j
arguments.
This has some implications for how one write functions that accept and pass arguments to data tables, as is explained really well in section 1.16 of the FAQs.
But I can't figure out how to take this one additional level.
Here is an example. Say I want to write a wrapper function foo()
that makes a specific summary of my data, and then a second wrapper plotfoo()
that calls foo()
and plots the result:
library(data.table)
foo <- function(data, by){
by <- substitute(by)
data[, .N, by=list(eval(by))]
}
DT <- data.table(mtcars)
foo(DT, gear)
OK, this works, because I get my tabulated results:
by N
1: 4 12
2: 3 15
3: 5 5
Now, I try to just the same when writing plotfoo()
but I fail miserably:
plotfoo <- function(data, by){
by <- substitute(by)
foo(data, eval(by))
}
plotfoo(DT, gear)
But this time I get an error message:
Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
OK, so the eval()
is causing a problem. Let's remove it:
plotfoo <- function(data, by){
by <- substitute(by)
foo(data, by)
}
plotfoo(DT, gear)
Oh no, I get a new error message:
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))]
And here is where I remain stuck.
Question: How to write a function that calls a function that calls data.table?
See Question&Answers more detail:
os