I just finished reading 'Programming with dplyr' and 'Define aesthetic mappings programatically' to start to get a grip on non-standard evaluation of functions. The specific question for this post is, "How do I write the code directly below using the tidyverse (eg quo()
, !!
, etc.)" instead of the base-R approach eval()
, substitute
, etc.
.
library(tidyverse)
xy <- data.frame(xvar = 1:10, yvar = 11:20)
plotfunc <- function(data, x, y){
y.sqr <- (eval(substitute(y), envir = data))^2
print(
ggplot(data, aes_q(x = substitute(x), y = substitute(y.sqr))) +
geom_line()
)
}
plotfunc(xy, xvar, yvar)
Can you provide the answer? It would be a bonus if you could work in the following concept, being, why is the function above non-standard whereas this other function below is standard? I read the Advanced R chapters on functions and non-standard evaluation, but it's above my head at this point. Can you explain in layperson terms? The function below is clear and concise (to me) whereas the function above is a hazy mess.
rescale01 <- function(x) {
rng <- range(x, na.rm = TRUE)
(x - rng[1]) / (rng[2] - rng[1])
}
rescale01(c(0, 5, 10))
You could do the following :
library(tidyverse)
xy <- data.frame(xvar = 1:10, yvar = 11:20)
plotfunc <- function(data, x, y){
x <- enquo(x)
y <- enquo(y)
print(
ggplot(data, aes(x = !!x, y = (!!y)^2)) +
geom_line()
)
}
plotfunc(xy, xvar, yvar)
Non standard evaluation basically means that you're passing the argument as an expression rather than a value. quo
and enquo
also associate an evaluation environment to this expression.
Hadley Wickham introduces it like this in his book :
In most programming languages, you can only access the values of a function’s arguments. In R, you can also access the code used to compute them. This makes it possible to evaluate code in non-standard ways: to use what is known as non-standard evaluation, or NSE for short. NSE is particularly useful for functions when doing interactive data analysis because it can dramatically reduce the amount of typing.
With rlang_0.4.0
, we can use the tidy-evaluation operator ({{...}}
) or curly-curly
which abstracts quote-and-unquote into a single interpolation step. This makes it easier to create functions
library(rlang)
library(ggplot2)
plotfunc <- function(data, x, y){
print(
ggplot(data, aes(x = {{x}}, y = {{y}}^2)) +
geom_line()
)
}
plotfunc(xy, xvar, yvar)
-output
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With