I have a question about the scope within which function names in data.table::dcast
calls are evaluated (data.table
version 1.9.6, R 3.2.2).
I'd like to make the function name, but this fails.
Here is what I have tried:
library(data.table)
DT <- data.table(value = c(1:10),
cat1 = c("a", "b", "a", "b", "a", "b", "a", "b", "c", "a"),
cat2 = c("x", "x", "x", "y", "y", "y", "y", "y", "y", "x"))
This works fine:
result1 <- dcast.data.table(DT, cat1 ~ cat2, value.var = "value", fun = sum)
Now I make my own function, which also works:
f1 <- function(x) {
y <- sum(x) ^ 2
return(y)
}
result2 <- dcast.data.table(DT, cat1 ~ cat2, value.var = "value", fun = f1)
Here I do the same thing, but I am creating a private function within a function. However, this fails with Error in eval(expr, envir, enclos) : could not find function "f2"
.
If I replace f2 with f1 it works and calls f1. It seems that it's looking at the global environment to evaluate the expression fun=f2, and f2 exists in the local scope only.
testFunction <- function(DT1) {
f2 <- function(x) {
y <- sum(x) ^ 2
return(y)
}
r3 <- dcast.data.table(DT1,cat1 ~ cat2, value.var = "value", fun = f2)
return(r3)
}
result3 <- testFunction(DT)
Is there any way around that? What I really wanted to do is make the function name f2 dynamic, so that I pass in, let's say, "f3", and it will call private function f3.
I would have hoped that something like
functionName = "f3"
r3 <- dcast.data.table(DT1, cat1 ~ cat2, value.var = "value", fun = get(functionName))
...would get me there, but this does not seem to work. Any ideas?
Based on the bug report I was able to work around the issue for now by using a parameter named "fun.aggregate".
Thanks for pointing me to it.
The code below works and achieves what I need. I can pass in a pre-existing function name such as mean or a locally defined function.
testFunction <- function(DT1,functionName="mean") {
f2 <- function(x) {
y <- sum(x) ^ 2
return(y)
}
fun.aggregate <- get(functionName)
r3 <- dcast.data.table(DT1,cat1~cat2,value.var="value",fun.aggregate=fun.aggregate)
return(r3)
}
result3 <- testFunction(DT,"mean")
result4 <- testFunction(DT,"f2")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With