Why is using list() critical for .dots = setNames() uses in dplyr?
I wrote an answer
about why setNames()
shows up sometimes in standard evaluation with dplyr.
My explanation turned into a mini-tutorial on why those standard evaluation
functions have a .dots
argument. The basic idea is that the usual variadic
argument ...
is a series of expressions that get evaluated inside of the
dataframe.
library(dplyr)
# standardize and round
z_round <- . %>% scale() %>% as.numeric() %>% round(2)
# The two expressions defining zMPG, zHP are the `...`
mtcars %>%
mutate_(
zMPG = ~ z_round(mpg),
zHP = ~ z_round(hp)
) %>%
as_tibble()
#> Warning: `mutate_()` was deprecated in dplyr 0.7.0.
#> Please use `mutate()` instead.
#> See vignette('programming') for more help
#> This warning is displayed once every 8 hours.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
#> # A tibble: 32 × 13
#> mpg cyl disp hp drat wt qsec vs am gear carb zMPG zHP
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4 0.15 -0.54
#> 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4 0.15 -0.54
#> 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1 0.45 -0.78
#> 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1 0.22 -0.54
#> 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2 -0.23 0.41
#> 6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1 -0.33 -0.61
#> 7 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4 -0.96 1.43
#> 8 24.4 4 147. 62 3.69 3.19 20 1 0 4 2 0.72 -1.24
#> 9 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2 0.45 -0.75
#> 10 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4 -0.15 -0.35
#> # … with 22 more rows
If we programmatically assemble or manipulate those expressions before calling
mutate_()
, we can’t use that ...
, because we have a list of expressions,
not a series of individual expressions. We use the .dots
argument instead.
exps <- list(
zMPG = ~ z_round(mpg),
zHP = ~ z_round(hp)
)
mtcars %>%
mutate_(exps)
#> Error in `compat_lazy()`:
#> ! Can't convert a list to a quosure.
mtcars %>%
mutate_(.dots = exps) %>%
as_tibble()
#> # A tibble: 32 × 13
#> mpg cyl disp hp drat wt qsec vs am gear carb zMPG zHP
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4 0.15 -0.54
#> 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4 0.15 -0.54
#> 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1 0.45 -0.78
#> 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1 0.22 -0.54
#> 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2 -0.23 0.41
#> 6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1 -0.33 -0.61
#> 7 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4 -0.96 1.43
#> 8 24.4 4 147. 62 3.69 3.19 20 1 0 4 2 0.72 -1.24
#> 9 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2 0.45 -0.75
#> 10 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4 -0.15 -0.35
#> # … with 22 more rows
[Jan. 4, 2021] Hello from the future
Here is how you would go about this in 2021 in the tidy evaluation framework.
Use an expression-list or a quosure-list and splice them in with !!!
.
exprs <- rlang::exprs(
zMPG = z_round(mpg),
zHP = z_round(hp)
)
# These are just expressions
exprs
#> $zMPG
#> z_round(mpg)
#>
#> $zHP
#> z_round(hp)
mtcars %>%
mutate(!!! exprs) %>%
as_tibble()
#> # A tibble: 32 × 13
#> mpg cyl disp hp drat wt qsec vs am gear carb zMPG zHP
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4 0.15 -0.54
#> 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4 0.15 -0.54
#> 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1 0.45 -0.78
#> 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1 0.22 -0.54
#> 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2 -0.23 0.41
#> 6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1 -0.33 -0.61
#> 7 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4 -0.96 1.43
#> 8 24.4 4 147. 62 3.69 3.19 20 1 0 4 2 0.72 -1.24
#> 9 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2 0.45 -0.75
#> 10 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4 -0.15 -0.35
#> # … with 22 more rows
quosures <- quos(
zMPG = z_round(mpg),
zHP = z_round(hp)
)
# These are expression-environment pairs
quosures
#> <list_of<quosure>>
#>
#> $zMPG
#> <quosure>
#> expr: ^z_round(mpg)
#> env: 0x000001c4fb613818
#>
#> $zHP
#> <quosure>
#> expr: ^z_round(hp)
#> env: 0x000001c4fb613818
mtcars %>%
mutate(!!! quosures) %>%
as_tibble()
#> # A tibble: 32 × 13
#> mpg cyl disp hp drat wt qsec vs am gear carb zMPG zHP
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4 0.15 -0.54
#> 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4 0.15 -0.54
#> 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1 0.45 -0.78
#> 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1 0.22 -0.54
#> 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2 -0.23 0.41
#> 6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1 -0.33 -0.61
#> 7 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4 -0.96 1.43
#> 8 24.4 4 147. 62 3.69 3.19 20 1 0 4 2 0.72 -1.24
#> 9 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2 0.45 -0.75
#> 10 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4 -0.15 -0.35
#> # … with 22 more rows
Last knitted on 2022-05-27. Source code on GitHub.1
-
.session_info #> ─ Session info ─────────────────────────────────────────────────────────────── #> setting value #> version R version 4.2.0 (2022-04-22 ucrt) #> os Windows 10 x64 (build 22000) #> system x86_64, mingw32 #> ui RTerm #> language (EN) #> collate English_United States.utf8 #> ctype English_United States.utf8 #> tz America/Chicago #> date 2022-05-27 #> pandoc NA #> #> ─ Packages ─────────────────────────────────────────────────────────────────── #> package * version date (UTC) lib source #> assertthat 0.2.1 2019-03-21 [1] CRAN (R 4.2.0) #> cli 3.3.0 2022-04-25 [1] CRAN (R 4.2.0) #> crayon 1.5.1 2022-03-26 [1] CRAN (R 4.2.0) #> DBI 1.1.2 2021-12-20 [1] CRAN (R 4.2.0) #> dplyr * 1.0.9 2022-04-28 [1] CRAN (R 4.2.0) #> ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.2.0) #> evaluate 0.15 2022-02-18 [1] CRAN (R 4.2.0) #> fansi 1.0.3 2022-03-24 [1] CRAN (R 4.2.0) #> generics 0.1.2 2022-01-31 [1] CRAN (R 4.2.0) #> git2r 0.30.1 2022-03-16 [1] CRAN (R 4.2.0) #> glue 1.6.2 2022-02-24 [1] CRAN (R 4.2.0) #> here 1.0.1 2020-12-13 [1] CRAN (R 4.2.0) #> knitr * 1.39 2022-04-26 [1] CRAN (R 4.2.0) #> lifecycle 1.0.1 2021-09-24 [1] CRAN (R 4.2.0) #> magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.2.0) #> pillar 1.7.0 2022-02-01 [1] CRAN (R 4.2.0) #> pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.2.0) #> purrr 0.3.4 2020-04-17 [1] CRAN (R 4.2.0) #> R6 2.5.1 2021-08-19 [1] CRAN (R 4.2.0) #> ragg 1.2.2 2022-02-21 [1] CRAN (R 4.2.0) #> rlang 1.0.2 2022-03-04 [1] CRAN (R 4.2.0) #> rprojroot 2.0.3 2022-04-02 [1] CRAN (R 4.2.0) #> rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.2.0) #> sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.2.0) #> stringi 1.7.6 2021-11-29 [1] CRAN (R 4.2.0) #> stringr 1.4.0 2019-02-10 [1] CRAN (R 4.2.0) #> systemfonts 1.0.4 2022-02-11 [1] CRAN (R 4.2.0) #> textshaping 0.3.6 2021-10-13 [1] CRAN (R 4.2.0) #> tibble 3.1.7 2022-05-03 [1] CRAN (R 4.2.0) #> tidyselect 1.1.2 2022-02-21 [1] CRAN (R 4.2.0) #> utf8 1.2.2 2021-07-24 [1] CRAN (R 4.2.0) #> vctrs 0.4.1 2022-04-13 [1] CRAN (R 4.2.0) #> xfun 0.31 2022-05-10 [1] CRAN (R 4.2.0) #> #> [1] C:/Users/Tristan/AppData/Local/R/win-library/4.2 #> [2] C:/Program Files/R/R-4.2.0/library #> #> ──────────────────────────────────────────────────────────────────────────────
Leave a comment