rdplyrtidyeval

In R how do I pass multiple variable names to a function using tidyeval


I would like to pass the names of several variables to a function that is using tidyeval.

I know I can pass the vars like this:

a_summary_fn <- function(the_data, the_group, vars) { 
  
  the_data |>  
    group_by({{the_group}}) |>  
    summarize(
      across(
        {{vars}},
        list(
          mean = ~mean(., na.rm = TRUE), 
          sd = ~sd(., na.rm = TRUE), 
          n = ~sum(!is.na(.))
        )
      )
    ) |>  
    mutate(across(ends_with(c("_mean", "_sd")), ~round(., digits = 3))) 
} 

a_summary_fn(mtcars, cyl, c(disp, hp))

but I was hoping to pass the analysis vars like arguments. Is there a way to pass them into a function by capturing the dots and converting them to variable names using tidyeval?

Ideally I want something like this:

a_summary_fn <- function(the_data, the_group, ...) { 
  
  the_data |>  
    group_by({{the_group}}) |>  
    summarize(
      across(
        ...,
        list(
          mean = ~mean(., na.rm = TRUE), 
          sd = ~sd(., na.rm = TRUE), 
          n = ~sum(!is.na(.))
        )
      )
    ) |>  
    mutate(across(ends_with(c("_mean", "_sd")), ~round(., digits = 3))) 
} 

a_summary_fn(mtcars, cyl, disp, hp)

Solution

  • You are close, just use c():

    a_summary_fn <- function(the_data, the_group, ...) { 
      
      the_data |>  
        group_by({{the_group}}) |>  
        summarize(
          across(
            c(...),
            list(
              mean = ~mean(., na.rm = TRUE), 
              sd = ~sd(., na.rm = TRUE), 
              n = ~sum(!is.na(.))
            )
          )
        ) |>  
        mutate(across(ends_with(c("_mean", "_sd")), ~round(., digits = 3))) 
    } 
    
    a_summary_fn(mtcars, cyl, disp, hp)
    

    If you were to write this out you would not do across(disp, hp, <function>), you would do across(c(disp, hp), <function>)

    Output

        cyl disp_mean disp_sd disp_n hp_mean hp_sd  hp_n
      <dbl>     <dbl>   <dbl>  <int>   <dbl> <dbl> <int>
    1     4      105.    26.9     11    82.6  20.9    11
    2     6      183.    41.6      7   122.   24.3     7
    3     8      353.    67.8     14   209.   51.0    14