Reputation: 7969
I have a list of aesthetics constructed programmatically and passed from other functions. They may contain any combination of aesthetics like alpha, colour, fill, etc., which is not know beforehand.
my_aes_list <- list(
x = "cty",
y = "hwy",
col = "trans")
I can use aes_string
to create aesthetics programmatically from this list:
library(ggplot2)
my_aes <- do.call(ggplot2::aes_string, my_aes_list)
ggplot(mpg) + geom_point(my_aes)
However aes_string()
was deprecated in ggplot2 3.0.0 and I would like to replace this code before it gets removed in a future version.
The documented alternative and several stack overflow questions indicate to use the .data[[
pronoun. However I can't find out how to use it with arbitrary programmatic aesthetics.
Doing something like:
my_data_list <- list()
for (name in names(my_aes_list)) {
my_data_list[[name]] <- .data[[my_aes_list[name]]]
}
obviously doesn't work outside of the aes
call itself. I also tried the !!!
injectors to no avail:
ggplot(mpg) + geom_point(aes(!!!my_aes_list))
seems to work but doesn't plot correctly.
What's the proper way to replace aes_string
and call ggplot
in this context?
Upvotes: 1
Views: 243
Reputation: 11
The 'tinycodet' R package provides aes_pro()
, which is equivalent to ggplot2::aes()
, except it uses formula inputs instead of non-standard evaluation. So you can do the following:
library(ggplot2)
data("mpg", package = "ggplot2")
my_aes_list <- list(
x = ~ cty,
y = ~ hwy,
col = ~ trans
)
my_aes <- do.call(tinycodet::aes_pro, my_aes_list) # create aes
ggplot(mpg) + geom_point(my_aes) # plot
Upvotes: 0
Reputation: 7969
One solution I found is to "defuse" the evaluation of the .data[[
pronoun with a call to expr()
:
my_data_list <- lapply(my_aes_list, function(x) ggplot2::expr(.data[[x]]))
Later, ggplot2::aes()
transparently evaluates these expressions:
my_aes <- do.call(ggplot2::aes, my_data_list)
ggplot(mpg) + geom_point(my_aes)
Upvotes: 1
Reputation: 26225
Interesting problem; another potential solution is to 'enquo(ensym(list))' then use the !!!
operator, i.e.
library(tidyverse)
library(rlang)
my_aes_list <- list(
x = "cty",
y = "hwy",
col = "trans")
my_list_quos <- as_quosures(map(my_aes_list, sym), env = .GlobalEnv)
my_list_quos
#> <list_of<quosure>>
#>
#> $x
#> <quosure>
#> expr: ^cty
#> env: global
#>
#> $y
#> <quosure>
#> expr: ^hwy
#> env: global
#>
#> $col
#> <quosure>
#> expr: ^trans
#> env: global
ggplot(mpg) + geom_point(aes(!!!my_list_quos))
Created on 2023-06-26 with reprex v2.0.2
Upvotes: 1