0

I'm writing a wrapper function for dplyr::summarize to add a summary row to a data frame. The goal is to provide the data frame, columns you'd like to summarize, the summary function, and any additional arguments for that function. Currently, the function works as long as args is not NULL. If no additional arguments are supplied, the function fails.

By changing ~do.call(.f, c(.x, args)) to ~do.call(.f, list(.x, args)), the function works when args is NULL, but fails when args is supplied (due to nested lists, as explained here).

Is there a way to define the function so that it will work whether or not args is supplied?

library(tidyverse)

set.seed(1234)
dat <- tibble(group = sample(letters, 10),
              var1 = c(rnorm(9), NA),
              var2 = rnorm(10))

my_func <- function(df, ..., .f = sum, args = NULL) {
  df %>%
    dplyr::bind_rows(
      dplyr::summarize_at(., dplyr::vars(...), ~do.call(.f, c(.x, args)))
    )
}

my_func(dat, var1, var2, .f = sum, args = list(na.rm = TRUE))
#> # A tibble: 11 x 3
#>    group    var1   var2
#>    <chr>   <dbl>  <dbl>
#>  1 p     -0.575  -0.110
#>  2 v     -0.547  -0.511
#>  3 e     -0.564  -0.911
#>  4 l     -0.890  -0.837
#>  5 o     -0.477   2.42 
#>  6 i     -0.998   0.134
#>  7 x     -0.776  -0.491
#>  8 f      0.0645 -0.441
#>  9 z      0.959   0.460
#> 10 d     NA      -0.694
#> 11 <NA>  -3.80   -0.985


my_func(dat, var1, var2, .f = sum)
#> Error: `summarise()` argument `var1` errored.
#> ℹ `var1` is `(structure(function (..., .x = ..1, .y = ..2, . = ..1) ...`.
#> x second argument must be a list

Created on 2020-02-28 by the reprex package (v0.3.0)

Jake Thompson
  • 2,591
  • 1
  • 16
  • 32

1 Answers1

1

This should be find if you use c() but make sure your first parameter is a list

my_func <- function(df, ..., .f = sum, args = NULL) {
  df %>%
    dplyr::bind_rows(
      dplyr::summarize_at(., dplyr::vars(...), ~do.call(.f, c(list(.x), args)))
    )
}
MrFlick
  • 195,160
  • 17
  • 277
  • 295