I would like to pass multiple functions at once to one purrr::map call, where the functions need some arguments. As pseudo code:
funs <- c(median, mean)
mtcars %>%
purrr::map(funs, na.rm = TRUE)
This code does not run, but is intended to show what I am looking for: passing over multiple functions to map
along with some arguments.
I looked at compose
but that function does something different.
You want to apply multiple functions to a dataframe with map(), but (apparently) there is no map() variation that does exactly this, only parts of it. For the multiple function part we have invoke_map() and for the multiple argument part over a dataframe we have pmap().
invoke_map()
allows the use of multiple functions at once. For example, if we want to generate 5 random variates for a uniform and normal distributions, the code is:
func <- list(runif, rnorm)
invoke_map(func, n = 5)
pmap()
is just like map, but it allows to pass multiple arguments to a single function. For example, if we want to generate 10 random variates from a normal distribution with mean = 0 and sd = 1, but also 100 random variates from a normal distribution with mean = 100 and sd = 20, the code looks like this:
args <- list(mean = c(0, 100), sd = c(1, 20), n = c(10, 100))
pmap(args, rnorm)
To solve your question, we have to combine both functions in the following way:
fun <- function(f) pmap(list(x = mtcars, na.rm = TRUE), f)
param <- list(list(mean), list(median))
invoke_map(.f = fun, .x = param)
How does this work?
At the invoke_map() level, fun
takes as arguments param
, which are the functions we want to apply to mtcars
.
Next, at the fun
level, these functions stored in param
are applied by pmap()
, one at a time, to each column in mtcars
.
Note: For the solution to really make sense, keep in mind the arguments invoke_map() and pmap() take.
More info about how invoke_map() and pmap() work.
invoke()
and its map variants have been retired in favour of rlang::exec()
. From the documentation:
These functions are retired in favour of exec(). They are no longer under active development but we will maintain them in the package indefinitely.
invoke() is retired in favour of the simpler exec() function reexported from rlang. exec() evaluates a function call built from its inputs and supports tidy dots
invoke_map() is retired without replacement because it is more complex to understand than the corresponding code using map(), map2() and exec()
So the equivalent method now is:
library(dplyr)
library(purrr)
funs <- c(mean = mean, median = median)
args <- list(na.rm = TRUE, trim = .1) # trim argument non-matching and ignored for median
mtcars %>%
map_df(~ funs %>%
map(exec, .x, !!!args), .id = "var")
# A tibble: 11 x 3
var mean median
<chr> <dbl> <dbl>
1 mpg 19.7 19.2
2 cyl 6.23 6
3 disp 223. 196.
4 hp 141. 123
5 drat 3.58 3.70
6 wt 3.15 3.32
7 qsec 17.8 17.7
8 vs 0.423 0
9 am 0.385 0
10 gear 3.62 4
11 carb 2.65 2
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