Search code examples
rdplyrrlang

Getting 'argument "e2" is missing with no default' error when using tidyeval within dplyr::summarize_at


I'm trying to capture a summarize_at operation across a bunch of variables. Here's a silly example:

library(dplyr)
library(stringr)

starwars %>%
  summarise_at(c("hair_color", "skin_color"), 
               ~ sum(if_else(str_detect(., "brown"), 1, birth_year), na.rm = TRUE))

# A tibble: 1 x 2
  hair_color skin_color
       <dbl>      <dbl>
1      2399.      3123.

Let's say that I want to capture this into a function, in which I can change birth_year to something else.

myfun <- function(df, var) {
  df %>% 
    summarize_at(c("hair_color", "skin_color"), 
                 ~ sum(if_else(str_detect(., "brown"), 1, !! enquo(var)), na.rm = TRUE))
}

myfun(starwars, birth_year)

Error in is_quosure(e2) : argument "e2" is missing, with no default 

What am I missing? I'm using dplyr v0.8.0.1, stringr v1.4, and rlang v0.3.1, running on R v3.5.3


Solution

  • I guess it is a bug, but in the meanwhile you can do

    myfun <- function(df, var) {
      df %>% 
        summarize_at(c("hair_color", "skin_color"), 
                     funs(sum(if_else(str_detect(., "brown"), 1, !! enquo(var)), na.rm = TRUE)))
    }
    myfun(starwars, birth_year)
    # A tibble: 1 x 2
    #   hair_color skin_color
    #        <dbl>      <dbl>
    # 1      2399.      3123.
    # Warning message:
    # funs() is soft deprecated as of dplyr 0.8.0
    # please use list() instead
    
    # # Before:
    # funs(name = f(.)
    
    # # After: 
    # list(name = ~f(.))  
    

    as a workaround. You get a soft-depreciation warning, but you should not follow the advise there, becasue the bug sits somewhere in teh enquosure of your function.