I am trying to take this canonical example for how the curly-curly operator works
mean_by <- function(data, by, var) {
data %>%
dplyr::group_by({{ by }}) %>%
dplyr::summarise(avg = mean({{ var }}, na.rm = TRUE))
}
mtcars %>% mean_by(by = cyl, var = disp)
and modify it by adding an additional variable to the grouping. Alas, I may never understand what that operator actually does; my attempts to do things like
mean_by <- function(data, by, var) {
data %>%
dplyr::group_by({{ c(by, hp) }}) %>%
dplyr::summarise(avg = mean({{ var }}, na.rm = TRUE))
}
mtcars %>% mean_by(by = cyl, var = disp)
clearly aren't working
A few years ago dplyr
added pick
to let people pass off {{}}
to data masking functions. So you can do something like this.
library(dplyr)
group_mean = \(data, by, var, ...) {
data |>
group_by(pick({{by}}), ...) |>
summarise(mean = mean({{var}}))
}
group_mean(starwars, by = c(homeworld, species), sex, var = mass)
#> `summarise()` has grouped output by 'homeworld', 'species'. You can override
#> using the `.groups` argument.
#> # A tibble: 64 × 4
#> # Groups: homeworld, species [57]
#> homeworld species sex mean
#> <chr> <chr> <chr> <dbl>
#> 1 Alderaan Human female 49
#> 2 Alderaan Human male NA
#> 3 Aleen Minor Aleena male 15
#> 4 Bespin Human male 79
#> 5 Bestine IV <NA> <NA> 110
#> 6 Cato Neimoidia Neimodian male 90
#> 7 Cerea Cerean male 82
#> 8 Champala Chagrian male NA
#> 9 Chandrila Human female NA
#> 10 Concord Dawn Human male 79
#> # ℹ 54 more rows
Created on 2024-09-18 with reprex v2.1.0
It would be possible to do this using rlang::enquos()
to defuse multiple expressions:
dplyr::group_by(hp, !!!rlang::enquos(by))
However, as this Tidyverse blog post states:
If you would like to pass multiple arguments to a data-masking verb, pass
...
directly
So in your case, to group by hp
and whatever else the caller passes:
mean_by_hp <- function(data, ..., var) {
data |>
dplyr::group_by(hp, ...) |>
dplyr::summarise(avg = mean({{ var }}, na.rm = TRUE))
}
mean_by_hp(mtcars, cyl, var = disp)
# hp cyl avg
# <dbl> <dbl> <dbl>
# 1 52 4 75.7
# 2 62 4 147.
# 3 65 4 71.1
# 4 66 4 78.8
# 5 91 4 120.
# 6 93 4 108
# 7 95 4 141.
# 8 97 4 120.
# 9 105 6 225
# 10 109 4 121
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