Reputation: 118
Let's say I have the following data.table
and would like to get the output below by referring to variables stored in a vector:
dt <- data.table(a = rep(1, 3),
b = rep(2, 3))
x <- 'a'
y <- 'b'
dt[, .(sum(get(x)), mean(get(y)))]
V1 V2
1: 3 2
Cool, it works. But now I'd like to make a function, and then do something like:
foo <- function(arg1, arg2) {
dt[, .(sum(get(arg1)), mean(get(arg2)))]
}
foo(x, y)
Realizing it works, I'd like to avoid calling all those gets
, and do something like:
foo <- function(arg1, arg2) {
eval(substitute(dt[, .(sum(arg1), mean(arg2))]))
}
foo(x, y) # or foo('x', 'y')
But this fails. Any idea on how to evaluate all the arguments at once in a way similar to calling get
multiple times?
Upvotes: 3
Views: 360
Reputation: 25225
Not sure if this is what you are looking for, another option is to force the as.name
conversion before calling substitute
:
foo <- function(arg1, arg2) {
A1 <- as.name(arg1);
A2 <- as.name(arg2);
eval(substitute(dt[, .(sum(A1), mean(A2))]))
}
dt <- data.table(a = rep(1, 3), b = rep(2, 3))
foo('a' 'b')
output:
V1 V2
1: 3 2
Upvotes: 3
Reputation: 887108
We can convert to sym
bol with as.symbol
or as.name
and eval
uate
foo <- function(arg1, arg2) {
dt[, .(sum(eval(as.name(arg1))), mean(eval(as.name(arg2))))]
}
foo(x, y)
# V1 V2
#1: 3 2
Or use [[
to subset the columns of the data.table
foo <- function(arg1, arg2) {
dt[, .(sum(.SD[[arg1]]), mean(.SD[[arg2]]))]
}
foo(x, y)
# V1 V2
#1: 3 2
Or another option is to paste
and eval/parse
foo <- function(arg1, arg2) {
eval(parse(text = paste0("dt[, .(sum(", arg1, "), mean(", arg2, "))]")))
}
foo(x, y)
# V1 V2
#1: 3 2
Upvotes: 4