# how to use a named variable within a function in r

by Jose   Last Updated June 29, 2018 00:26 AM

Assume the following dummy data frame:

``````dt <- data.table(A=c("a", "a", "a", "b", "b", "b", "c", "c", "c", "d", "d", "d"),
B=c("e", "e", "e", "e", "e", "e", "f", "f", "f", "f", "f", "f"),
C=1:12,
D=13:24)
``````

I'd like to calculate some stadistics (say, mean and standard deviation) per each numeric column ("C" and "D") and each time grouped by the factor columns c("A"), c("B"), and c("A", "B). In the actual data frame, I have about 40 numeric columns, 10 factor columns that group in different combinations and a large list of statistics I'd like to calculate. Based on the answer (by @thelatemail) I got from a previous question, I know I can use the code below to deal with factor groupings (by=) using a list:

``````groupList <- list(c("A", "B"), c("A"), c("B"))
out <- vector("list", 3)
out <- lapply(
groupList,
function(x) {
dt[, .(mean=mean(C), sd=sd(C)), by=x]
}
)
``````

Now I'd like to go a step further and create a variable containing a list of the names of numeric columns in the data frame and use the name of that variable within the function above. I came out with the following code but unfortunately, it doesn't work. My idea is to use a loop to extract a value from measureList at each turn and place that value within the mean, sd functions. Any ideas? The loop is how I tend to think of these things but I'll be glad to get rid of it if it makes the code faster or more efficient (particularly because one of the factor columns I have has 90 levels). I'd appreciate any pointer to solve this problem! Thanks.

``````factorList <- list(c("A"), c("B"), c("A", "B"))
measureList <- list(c("C"), c("D"))

out <- vector("list", 2)
for(i in 1:length(measureList)){
out[[i]] <-lapply(
factorList,
function(x) {
dt[, .(mean=mean(eval(measureList[[i]])),
sd=sd(eval(measureList[[i]]))),
by = x]
}
)
}
``````
Tags :

This uses `dplyr` and `purrr`, but I think it works.

``````library(dplyr)
library(purrr)

combos <- expand.grid(factorList, measureList)
map2(combos[, 1],
combos[, 2],
~ dt %>% group_by_at(.x) %>% summarize_at(.y, funs(mean, sd)))
``````

You can use `outer` with a vectorized function or use `Map` as shown below:

``````m = function(x,y)dt[, .(mean=mean(get(y)), sd=sd(get(y))), by=x]

c(outer(factorList,measureList,Vectorize(m)))
``````

or

``````Map(m,rep(factorList,each=length(measureList)),measureList)
``````