I would like to wrap mget()
in a simple function so that it returns an unnamed list, and use this function within data.table j.
I've printed out the environment within the function body passed to data.table j. I found data.table j uses one environment when calling my function, and another when using unname(mget())
. I have tried playing around with inherits, but used inherits=F
here to be more strict about where we find the relevant variables.
This approach works:
library(data.table); library(purrr)
# a list of functions the user can access
functionDictionary <- list(
sum = sum,
weighted_sum = function(x,y) sum(x)/sum(y)
)
grouping_vars <- c('cyl', 'vs')
# user defines here which calculations they wish to make with which
# columns
userList <- list(
reactive = list(names = c('my_var1', 'my_var2'),
calculations = list(
sum = c('hp'),
weighted_sum=c('hp', 'mpg')
))
)
mtcars <- data.table(mtcars)
mtcars[,
{
env <- environment() # get env in datatable j
print('grouping')
print(names(env))
functionList <-
map2(names(userList[['reactive']]$calculations),
userList[['reactive']]$calculations,
~ do.call(functionDictionary[[.x]],
unname(mget(.y, envir=env,
inherits=F)))
)
functionList # last expression in `{` is returned
}
,
by=grouping_vars
]
However, adding a simple wrapper to mget()
fails to find 'hp', and indeed, it is not listed in the environment of the function body passed to data.table j.
mget_unnamed <- function(x,...) unname(mget(x, inherits=F, ...))
mtcars[,
{
env <- environment() # get env in datatable j
print('grouping')
print(names(env))
functionList <-
map2(names(userList[['reactive']]$calculations),
userList[['reactive']]$calculations,
~ do.call(functionDictionary[[.x]],
mget_unnamed(.y, envir=env))
)
functionList # last expression in `{` is returned
}
,
by=grouping_vars
]
The error is: "Error: value for ‘hp’ not found."