Skip to content

Commit b9e1694

Browse files
Update docs related to tidyeval (#4827)
1 parent 061cec2 commit b9e1694

File tree

5 files changed

+189
-115
lines changed

5 files changed

+189
-115
lines changed

R/aes.r

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,9 @@ NULL
6565
#' scatter_by(mtcars, disp, drat)
6666
#'
6767
#' # If your wrapper has a more specific interface with named arguments,
68-
#' # you need "enquote and unquote":
68+
#' # you need the "embrace operator":
6969
#' scatter_by <- function(data, x, y) {
70-
#' x <- enquo(x)
71-
#' y <- enquo(y)
72-
#'
73-
#' ggplot(data) + geom_point(aes(!!x, !!y))
70+
#' ggplot(data) + geom_point(aes({{ x }}, {{ y }}))
7471
#' }
7572
#' scatter_by(mtcars, disp, drat)
7673
#'
@@ -248,9 +245,18 @@ is_position_aes <- function(vars) {
248245
#'
249246
#' @section Life cycle:
250247
#'
251-
#' All these functions are soft-deprecated. Please use tidy evaluation
252-
#' idioms instead (see the quasiquotation section in
253-
#' [aes()] documentation).
248+
#' All these functions are soft-deprecated. Please use tidy evaluation idioms
249+
#' instead. Regarding `aes_string()`, you can replace it with `.data` pronoun.
250+
#' For example, the following code can achieve the same mapping as
251+
#' `aes_string(x_var, y_var)`.
252+
#'
253+
#' ``` r
254+
#' x_var <- "foo"
255+
#' y_var <- "bar"
256+
#' aes(.data[[x_var]], .data[[y_var]])
257+
#' ````
258+
#'
259+
#' For more details, please see `vignette("ggplot2-in-packages")`.
254260
#'
255261
#' @param x,y,... List of name value pairs. Elements must be either
256262
#' quoted calls, strings, one-sided formulas or constants.
@@ -259,23 +265,6 @@ is_position_aes <- function(vars) {
259265
#' @keywords internal
260266
#'
261267
#' @export
262-
#' @examples
263-
#' # Three ways of generating the same aesthetics
264-
#' aes(mpg, wt, col = cyl)
265-
#' aes_(quote(mpg), quote(wt), col = quote(cyl))
266-
#' aes_(~mpg, ~wt, col = ~cyl)
267-
#' aes_string("mpg", "wt", col = "cyl")
268-
#'
269-
#' # You can't easily mimic these calls with aes_string
270-
#' aes(`$100`, colour = "smooth")
271-
#' aes_(~ `$100`, colour = "smooth")
272-
#' # Ok, you can, but it requires a _lot_ of quotes
273-
#' aes_string("`$100`", colour = '"smooth"')
274-
#'
275-
#' # Convert strings to names with as.name
276-
#' var <- "cyl"
277-
#' aes(col = x)
278-
#' aes_(col = as.name(var))
279268
aes_ <- function(x, y, ...) {
280269
lifecycle::deprecate_soft(
281270
"3.0.0",

R/utilities-tidy-eval.R

Lines changed: 95 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,102 @@
11
#' Tidy eval helpers
22
#'
33
#' @description
4+
#' This page lists the tidy eval tools reexported in this package from
5+
#' rlang. To learn about using tidy eval in scripts and packages at a
6+
#' high level, see the [dplyr programming
7+
#' vignette](https://dplyr.tidyverse.org/articles/programming.html)
8+
#' and the [ggplot2 in packages
9+
#' vignette](https://ggplot2.tidyverse.org/articles/ggplot2-in-packages.html).
10+
#' The [Metaprogramming
11+
#' section](https://adv-r.hadley.nz/metaprogramming.html) of [Advanced
12+
#' R](https://adv-r.hadley.nz) may also be useful for a deeper dive.
413
#'
5-
#' * \code{\link[rlang]{sym}()} creates a symbol from a string and
6-
#' \code{\link[rlang:sym]{syms}()} creates a list of symbols from a
7-
#' character vector.
8-
#'
9-
#' * \code{\link[rlang:nse-defuse]{enquo}()} and
10-
#' \code{\link[rlang:nse-defuse]{enquos}()} delay the execution of one or
11-
#' several function arguments. \code{enquo()} returns a single quoted
12-
#' expression, which is like a blueprint for the delayed computation.
13-
#' \code{enquos()} returns a list of such quoted expressions.
14-
#'
15-
#' * \code{\link[rlang:nse-defuse]{expr}()} quotes a new expression _locally_. It
16-
#' is mostly useful to build new expressions around arguments
17-
#' captured with [enquo()] or [enquos()]:
18-
#' \code{expr(mean(!!enquo(arg), na.rm = TRUE))}.
19-
#'
20-
#' * \code{\link[rlang]{as_name}()} transforms a quoted variable name
21-
#' into a string. Supplying something else than a quoted variable
22-
#' name is an error.
23-
#'
24-
#' That's unlike \code{\link[rlang]{as_label}()} which also returns
25-
#' a single string but supports any kind of R object as input,
26-
#' including quoted function calls and vectors. Its purpose is to
27-
#' summarise that object into a single label. That label is often
28-
#' suitable as a default name.
29-
#'
30-
#' If you don't know what a quoted expression contains (for instance
31-
#' expressions captured with \code{enquo()} could be a variable
32-
#' name, a call to a function, or an unquoted constant), then use
33-
#' \code{as_label()}. If you know you have quoted a simple variable
34-
#' name, or would like to enforce this, use \code{as_name()}.
35-
#'
36-
#' To learn more about tidy eval and how to use these tools, visit
37-
#' \url{https://tidyeval.tidyverse.org} and the
38-
#' \href{https://adv-r.hadley.nz/metaprogramming.html}{Metaprogramming
39-
#' section} of \href{https://adv-r.hadley.nz}{Advanced R}.
14+
#' * The tidy eval operators `{{`, `!!`, and `!!!` are syntactic
15+
#' constructs which are specially interpreted by tidy eval functions.
16+
#' You will mostly need `{{`, as `!!` and `!!!` are more advanced
17+
#' operators which you should not have to use in simple cases.
18+
#'
19+
#' The curly-curly operator `{{` allows you to tunnel data-variables
20+
#' passed from function arguments inside other tidy eval functions.
21+
#' `{{` is designed for individual arguments. To pass multiple
22+
#' arguments contained in dots, use `...` in the normal way.
23+
#'
24+
#' ```
25+
#' my_function <- function(data, var, ...) {
26+
#' data %>%
27+
#' group_by(...) %>%
28+
#' summarise(mean = mean({{ var }}))
29+
#' }
30+
#' ```
31+
#'
32+
#' * [enquo()] and [enquos()] delay the execution of one or several
33+
#' function arguments. The former returns a single expression, the
34+
#' latter returns a list of expressions. Once defused, expressions
35+
#' will no longer evaluate on their own. They must be injected back
36+
#' into an evaluation context with `!!` (for a single expression) and
37+
#' `!!!` (for a list of expressions).
38+
#'
39+
#' ```
40+
#' my_function <- function(data, var, ...) {
41+
#' # Defuse
42+
#' var <- enquo(var)
43+
#' dots <- enquos(...)
44+
#'
45+
#' # Inject
46+
#' data %>%
47+
#' group_by(!!!dots) %>%
48+
#' summarise(mean = mean(!!var))
49+
#' }
50+
#' ```
51+
#'
52+
#' In this simple case, the code is equivalent to the usage of `{{`
53+
#' and `...` above. Defusing with `enquo()` or `enquos()` is only
54+
#' needed in more complex cases, for instance if you need to inspect
55+
#' or modify the expressions in some way.
56+
#'
57+
#' * The `.data` pronoun is an object that represents the current
58+
#' slice of data. If you have a variable name in a string, use the
59+
#' `.data` pronoun to subset that variable with `[[`.
60+
#'
61+
#' ```
62+
#' my_var <- "disp"
63+
#' mtcars %>% summarise(mean = mean(.data[[my_var]]))
64+
#' ```
65+
#'
66+
#' * Another tidy eval operator is `:=`. It makes it possible to use
67+
#' glue and curly-curly syntax on the LHS of `=`. For technical
68+
#' reasons, the R language doesn't support complex expressions on
69+
#' the left of `=`, so we use `:=` as a workaround.
70+
#'
71+
#' ```
72+
#' my_function <- function(data, var, suffix = "foo") {
73+
#' # Use `{{` to tunnel function arguments and the usual glue
74+
#' # operator `{` to interpolate plain strings.
75+
#' data %>%
76+
#' summarise("{{ var }}_mean_{suffix}" := mean({{ var }}))
77+
#' }
78+
#' ```
79+
#'
80+
#' * Many tidy eval functions like `dplyr::mutate()` or
81+
#' `dplyr::summarise()` give an automatic name to unnamed inputs. If
82+
#' you need to create the same sort of automatic names by yourself,
83+
#' use `as_label()`. For instance, the glue-tunnelling syntax above
84+
#' can be reproduced manually with:
85+
#'
86+
#' ```
87+
#' my_function <- function(data, var, suffix = "foo") {
88+
#' var <- enquo(var)
89+
#' prefix <- as_label(var)
90+
#' data %>%
91+
#' summarise("{prefix}_mean_{suffix}" := mean(!!var))
92+
#' }
93+
#' ```
94+
#'
95+
#' Expressions defused with `enquo()` (or tunnelled with `{{`) need
96+
#' not be simple column names, they can be arbitrarily complex.
97+
#' `as_label()` handles those cases gracefully. If your code assumes
98+
#' a simple column name, use `as_name()` instead. This is safer
99+
#' because it throws an error if the input is not a name as expected.
40100
#'
41101
#' @md
42102
#' @name tidyeval

man/aes.Rd

Lines changed: 2 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/aes_.Rd

Lines changed: 9 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/tidyeval.Rd

Lines changed: 69 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)