I have a function that takes as an argument a list of functions.
library(moments)
library(plyr)
tests <- list(mean, varience, skewness, kurtosis)
f <- function(X, tests){
out <- each(... = tests)(X) #each from plyr
names(out) <- GetNames(tests)
out
}
I want GetNames
to take the list of objects, in this case functions, and return the names of the objects as text. Ideally, I'd like GetNames
to work with any list of named objects:
> GetNames(tests)
[1] "mean" "varience" "skewness" "kurtosis"
as.character(tests)
returns the text of the code of each function, not their names.
I tried:
GN <- function(X) deparse(substitute(X))
GetNames <- function(X) lapply(tests, GN)
GetNames(tests)
But this returns:
[[1]]
[1] "X[[i]]"
[[2]]
[1] "X[[i]]"
[[3]]
[1] "X[[i]]"
[[4]]
[1] "X[[i]]"
I have some version of this problem frequently when writing R code. I want a function to evaluate its argument some number of steps, here one step from tests
to the names of its objects, and then stop and let me do something to the result, here convert them to strings, rather than going on to get the referents of the names before I can grab them (the names).
Once you run
tests <- list(mean, varience, skewness, kurtosis)
those symbols are evaluated and discarded. If you look at
tests[[2]]
or something, you can see there really isn't an original reference to varience
, but rather the funcion that the symbol varience
pointed to is now stored in a list. (Things work a bit differently when passing parameters to functions thanks to the promises and the call stack but that's not what you're doing here). There is no lazy-evaluation for list()
after you've run it.
If you want to keep the names of the functions, it's probably best to work with a named list. You can make a helper function like
nlist <- function(...) { dots<-substitute(...()); setNames(list(...), sapply(dots, deparse))}
tests <- nlist(mean, var, skewness, kurtosis)
Now the values are preserved as names
names(tests)
# [1] "mean" "var" "skewness" "kurtosis"