Consider the minimal working example
library(tidyverse)
myplot <- function(df, x, y) {
df |>
ggplot(aes(x, y))
geom_point()
}
iris |>
myplot(Petal.Width, Petal.Length)
It raises Error in FUN(X[[i]], ...) : object 'Petal.Width' not found
. How do I delay the evaluation of Petal.Width
and Petal.Length
to ggplot
?
CodePudding user response:
One option would be to use curly-curly {{
which replaces the old pattern of using bang-bang !!
enquo
. For more info see
What is data-masking and why do I need {{? and the ggplot2 book for using {{
in a ggplot2
context:
library(tidyverse)
myplot <- function(df, x, y) {
df |>
ggplot(aes({{ x }}, {{ y }}))
geom_point()
}
iris |>
myplot(Petal.Width, Petal.Length)
CodePudding user response:
1) dot dot dot R's dot dot dot works here:
myplot <- function(df, ...) {
df |>
ggplot(aes(...))
geom_point()
}
iris |>
myplot(Petal.Width, Petal.Length)
2) aes_string Another possibility is to use standard evaluation with aes_string
.
myplot <- function(df, x, y) {
df |>
ggplot(aes_string(x, y))
geom_point()
}
iris |>
myplot("Petal.Width", "Petal.Length")
3) formula A variation of (2) which also uses aes_string
is to pass a formula. Use all.vars
to extract the variable names.
myplot <- function(df, formula) {
v <- all.vars(formula)
df |>
ggplot(aes_string(v[2], v[1]))
geom_point()
}
iris |>
myplot(Petal.Length ~ Petal.Width)
4) plot/xyplot plot (base R) and lattice::xyplot arguments are the same as (3) except for order giving trivial implementations.
library(lattice)
myplot <- function(df, formula) {
plot(formula, df)
}
iris |>
myplot(Petal.Length ~ Petal.Width)
library(lattice)
myplot <- function(df, formula) {
xyplot(formula, df)
}
iris |>
myplot(Petal.Length ~ Petal.Width)
CodePudding user response:
Using non-standard evaluation https://www.r-bloggers.com/2019/07/bang-bang-how-to-program-with-dplyr/
library(tidyverse)
myplot <- function(df, x, y) {
df |>
ggplot(aes(!!x, !!y))
geom_point()
}
iris |>
myplot(quo(Petal.Width), quo(Petal.Length))