I'm trying to capture a summarize_at
operation across a bunch of variables. Here's a silly example:
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
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) {
var <- enquo(var)
df %>%
summarize_at(c("hair_color", "skin_color"),
~ sum(if_else(str_detect(., "brown"), 1, !! 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.
EDIT: Ok, I think this is a bug, because this works:
myfun <- function(df, var) {
var <- enquo(var)
df %>%
summarize_at(c("hair_color", "skin_color"),
funs(sum(if_else(str_detect(., "brown"), 1, !! var), na.rm = TRUE)))
}
myfun(starwars, birth_year)
#> 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: 1 x 2
#> hair_color skin_color
#> <dbl> <dbl>
#> 1 2399. 3123.
EDIT2: I see there's some discussion about this already here: https://github.com/tidyverse/dplyr/issues/4199
I'm not clear however on what would be the best practice after funs()
is fully deprecated. The suggestions that are being thrown around in that thread seem pretty daunting to me.