While working with dplyr
pipeline, I would like to pass a function to mutate
using NSE
with the function name being passed from a vector.
Given vector of two function names:
funs <- c("sum", "mean")
I would like to use first value to obtain sum:
require(dplyr)
mtcars %>%
group_by(cyl) %>%
mutate_(res = funs[1](hp))
This results in an error:
Error in as.lazy_dots(list(...)) : attempt to apply non-function
do.call
do.call
based solution seems to generate some results for sum:
mtcars %>%
group_by(cyl) %>%
mutate_(res = do.call(funs[1], .))
but it fails when trying to use mean
:
>> mtcars %>%
+ group_by(cyl) %>%
+ mutate_(res = do.call(funs[2], .))
Error in mean.default(mpg = c(21, 21, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, :
argument "x" is missing, with no default
I'm guessing that it simply makes no sense in the way it is applied here. Hence my question: how to use nse in dplyr
so the function can be passed as a string from a vector?
We can use get
and get
extracts the values of a single string. Here, it is a function, so it returns the function itself.
mtcars %>%
group_by(cyl) %>%
mutate(res= get(funs[1])(hp))
For passing additional arguments
mtcars$hp[1] <- NA
mtcars %>%
group_by(cyl) %>%
mutate(res= get(funs[1])(hp, na.rm = TRUE))