|
8 | 8 | #' [ggplot2()] and in individual layers.
|
9 | 9 | #'
|
10 | 10 | #' This function also standardises aesthetic names by converting `color` to `colour`
|
11 |
| -#' (also in substrings, e.g. `point_color` to `point_colour`) and translating old style |
12 |
| -#' R names to ggplot names (eg. `pch` to `shape`, `cex` to `size`). |
| 11 | +#' (also in substrings, e.g., `point_color` to `point_colour`) and translating old style |
| 12 | +#' R names to ggplot names (e.g., `pch` to `shape` and `cex` to `size`). |
13 | 13 | #'
|
14 | 14 | #' @section Quasiquotation:
|
15 | 15 | #'
|
|
22 | 22 | #' programming vignette](http://dplyr.tidyverse.org/articles/programming.html)
|
23 | 23 | #' to learn more about these techniques.
|
24 | 24 | #'
|
25 |
| -#' @param x,y,... List of name value pairs giving aesthetics to map to |
26 |
| -#' variables. The names for x and y aesthetics are typically omitted because |
27 |
| -#' they are so common; all other aesthetics must be named. |
| 25 | +#' @param x,y,... List of name-value pairs in the form `aesthetic = variable` |
| 26 | +#' describing which variables in the layer data should be mapped to which |
| 27 | +#' aesthetics used by the paired geom/stat. The expression `variable` is |
| 28 | +#' evaluated within the layer data, so there is no need to refer to |
| 29 | +#' the original dataset (i.e., use `ggplot(df, aes(variable))` |
| 30 | +#' instead of `ggplot(df, aes(df$variable))`). The names for x and y aesthetics |
| 31 | +#' are typically omitted because they are so common; all other aesthetics must be named. |
28 | 32 | #' @seealso [vars()] for another quoting function designed for
|
29 | 33 | #' faceting specifications.
|
30 | 34 | #' @return A list with class `uneval`. Components of the list are either
|
@@ -334,3 +338,55 @@ mapped_aesthetics <- function(x) {
|
334 | 338 | is_null <- vapply(x, is.null, logical(1))
|
335 | 339 | names(x)[!is_null]
|
336 | 340 | }
|
| 341 | + |
| 342 | + |
| 343 | +#' Check a mapping for discouraged usage |
| 344 | +#' |
| 345 | +#' Checks that `$` and `[[` are not used when the target *is* the data |
| 346 | +#' |
| 347 | +#' @param mapping A mapping created with [aes()] |
| 348 | +#' @param data The data to be mapped from |
| 349 | +#' |
| 350 | +#' @noRd |
| 351 | +warn_for_aes_extract_usage <- function(mapping, data) { |
| 352 | + lapply(mapping, function(quosure) { |
| 353 | + warn_for_aes_extract_usage_expr(get_expr(quosure), data, get_env(quosure)) |
| 354 | + }) |
| 355 | +} |
| 356 | + |
| 357 | +warn_for_aes_extract_usage_expr <- function(x, data, env = emptyenv()) { |
| 358 | + if (is_call(x, "[[") || is_call(x, "$")) { |
| 359 | + if (extract_target_is_likely_data(x, data, env)) { |
| 360 | + good_usage <- alternative_aes_extract_usage(x) |
| 361 | + warning( |
| 362 | + "Use of `", format(x), "` is discouraged. ", |
| 363 | + "Use `", good_usage, "` instead.", |
| 364 | + call. = FALSE |
| 365 | + ) |
| 366 | + } |
| 367 | + } else if (is.call(x)) { |
| 368 | + lapply(x, warn_for_aes_extract_usage_expr, data, env) |
| 369 | + } |
| 370 | +} |
| 371 | + |
| 372 | +alternative_aes_extract_usage <- function(x) { |
| 373 | + if (is_call(x, "[[")) { |
| 374 | + good_call <- call2("[[", quote(.data), x[[3]]) |
| 375 | + format(good_call) |
| 376 | + } else if (is_call(x, "$")) { |
| 377 | + as.character(x[[3]]) |
| 378 | + } else { |
| 379 | + stop("Don't know how to get alternative usage for `", format(x), "`", call. = FALSE) |
| 380 | + } |
| 381 | +} |
| 382 | + |
| 383 | +extract_target_is_likely_data <- function(x, data, env) { |
| 384 | + if (!is.name(x[[2]])) { |
| 385 | + return(FALSE) |
| 386 | + } |
| 387 | + |
| 388 | + tryCatch({ |
| 389 | + data_eval <- eval_tidy(x[[2]], data, env) |
| 390 | + identical(data_eval, data) |
| 391 | + }, error = function(err) FALSE) |
| 392 | +} |
0 commit comments