The package data.table
has some special syntax that requires one to use expressions as the i
and j
arguments.
This has some im
I think you might be tieing yourself up in knots. This works:
library(data.table)
foo <- function(data, by){
by <- by
data[, .N, by=by]
}
DT <- data.table(mtcars)
foo(DT, 'gear')
plotfoo <- function(data, by){
foo(data, by)
}
plotfoo(DT, 'gear')
And that method supports passing in character values:
> gg <- 'gear'
> plotfoo <- function(data, by){
+ foo(data, by)
+ }
> plotfoo(DT, gg)
gear N
1: 4 12
2: 3 15
3: 5 5
This will work:
plotfoo <- function(data, by) {
by <- substitute(by)
do.call(foo, list(quote(data), by))
}
plotfoo(DT, gear)
# by N
# 1: 4 12
# 2: 3 15
# 3: 5 5
Explanation:
The problem is that your call to foo()
in plotfoo()
looks like one of the following:
foo(data, eval(by))
foo(data, by)
When foo
processes those calls, it dutifully substitute
s for the second formal argument (by
) getting as by
's value the symbols eval(by)
or by
. But you want by
's value to be gear
, as in the call foo(data, gear)
.
do.call()
solves this problem by evaluating the elements of its second argument before constructing the call that it then evaluates. As a result, when you pass it by
, it evaluates it to its value (the symbol gear
) before constructing a call that looks (essentially) like this:
foo(data, gear)