2

I was trying to pass a list of functions into dplyr summerize_at function and got a warning:

library(tidyverse)
library(purrr)

p <- c(0.2, 0.5, 0.8)

p_names <- map_chr(p, ~paste0(.x*100, "%"))

p_funs <- map(p, ~partial(quantile, probs = .x, na.rm = TRUE)) %>% 
  set_names(nm = p_names)

mtcars %>% 
  group_by(cyl) %>% 
  summarize_at(vars(mpg), funs(!!!p_funs))
#> Warning: funs() is soft deprecated as of dplyr 0.8.0
#> please use list() instead
#> 
#> # Before:
#> funs(name = f(.)
#> 
#> # After: 
#> list(name = ~f(.))
#> This warning is displayed once per session.
#> # A tibble: 3 x 4
#>     cyl `20%` `50%` `80%`
#>   <dbl> <dbl> <dbl> <dbl>
#> 1     4  22.8  26    30.4
#> 2     6  18.3  19.7  21  
#> 3     8  13.9  15.2  16.8

I then changed the funs to list but couldn't find a way to unquote the list of funs.

mtcars %>% 
  group_by(cyl) %>% 
  summarize_at(vars(mpg), list(~ !!!p_funs))
#> Error in !p_funs: invalid argument type

mtcars %>% 
  group_by(cyl) %>% 
  summarize_at(vars(mpg), list(~ {{p_funs}}))
#> Error: Column `mpg` must be length 1 (a summary value), not 3
C.Liu
  • 343
  • 3
  • 5

1 Answers1

3

list doesn't support splicing (!!!), use list2 or lst instead :

mtcars %>% 
  group_by(cyl) %>% 
  summarize_at(vars(mpg), rlang::list2(!!!p_funs))
# # A tibble: 3 x 4
#     cyl `20%` `50%` `80%`
#   <dbl> <dbl> <dbl> <dbl>
# 1     4  22.8  26    30.4
# 2     6  18.3  19.7  21  
# 3     8  13.9  15.2  16.8

mtcars %>% 
  group_by(cyl) %>% 
  summarize_at(vars(mpg), lst(!!!p_funs))
# # A tibble: 3 x 4
#     cyl `20%` `50%` `80%`
#   <dbl> <dbl> <dbl> <dbl>
# 1     4  22.8  26    30.4
# 2     6  18.3  19.7  21  
# 3     8  13.9  15.2  16.8

Though here the simplest is just to do :

mtcars %>% 
  group_by(cyl) %>% 
  summarize_at(vars(mpg), p_funs)
# # A tibble: 3 x 4
#     cyl `20%` `50%` `80%`
#   <dbl> <dbl> <dbl> <dbl>
# 1     4  22.8  26    30.4
# 2     6  18.3  19.7  21  
# 3     8  13.9  15.2  16.8
moodymudskipper
  • 46,417
  • 11
  • 121
  • 167
  • Using features of the package `rlang`, a function can recognize the sequences `!!!` and `!!` and adopt the relevant behavior. `list` is a base function and base R will most probably never integrate these features. Typically, most functions from *tidyverse* packages support quasiquotation. Read more here : https://adv-r.hadley.nz/quasiquotation.html – moodymudskipper May 31 '19 at 09:31