Reputation: 2319
So this example is basically from https://tidyeval.tidyverse.org/dplyr.html#patterns-for-single-arguments and it works just fine:
library(tidyverse)
group_mean <- function(df, group_var, summary_var){
group_var <- rlang::enquo(group_var)
summary_var <-rlang::enquo(summary_var)
name <- paste0(rlang::quo_name(summary_var), "_mean")
df %>%
dplyr::group_by(!!group_var) %>%
dplyr::summarise(!!name := mean(!!summary_var, na.rm = TRUE))
}
mtcars %>% group_mean(group_var = cyl, summary_var = disp)
#> # A tibble: 3 x 2
#> cyl disp_mean
#> <dbl> <dbl>
#> 1 4 105.
#> 2 6 183.
#> 3 8 353.
I would like to e.g. be able to choose median instead of mean sometimes and e.g. change the function name to group_stat()
.
Upvotes: 3
Views: 107
Reputation: 2101
You can do something like this. I'm not quite sure exactly how this works but I've seen this method used in the source code of library(purrr)
for as_mapper()
:
https://github.com/tidyverse/purrr/blob/master/R/as_mapper.R
library(tidyverse)
group_stat <- function(df, group_var, summary_var, .f) {
func <- rlang::as_closure(.f)
group_var <- rlang::enquo(group_var)
summary_var <-rlang::enquo(summary_var)
name <- paste0(rlang::quo_name(summary_var), "_", deparse(substitute(.f)))
df %>%
dplyr::group_by(!!group_var) %>%
dplyr::summarise(!!name := func(!!summary_var, na.rm = TRUE))
}
mtcars %>%
group_stat(group_var = cyl, summary_var = disp, median)
#> # A tibble: 3 x 2
#> cyl disp_median
#> <dbl> <dbl>
#> 1 4 108
#> 2 6 168.
#> 3 8 350.
mtcars %>%
group_stat(group_var = cyl, summary_var = disp, mean)
#> # A tibble: 3 x 2
#> cyl disp_mean
#> <dbl> <dbl>
#> 1 4 105.
#> 2 6 183.
#> 3 8 353.
mtcars %>%
group_stat(group_var = cyl, summary_var = disp, max)
#> # A tibble: 3 x 2
#> cyl disp_max
#> <dbl> <dbl>
#> 1 4 147.
#> 2 6 258
#> 3 8 472
mtcars %>%
group_stat(group_var = cyl, summary_var = disp, min)
#> # A tibble: 3 x 2
#> cyl disp_min
#> <dbl> <dbl>
#> 1 4 71.1
#> 2 6 145
#> 3 8 276.
Created on 2019-05-02 by the reprex package (v0.2.1)
Upvotes: 6