19.5 Non-quoting
Base R has one function that implements quasiquotation: bquote(). It uses .() for unquoting:
xyz <- bquote((x + y + z))
bquote(-.(xyz) / 2)
#> -(x + y + z)/2bquote() isn’t used by any other function in base R, and has had relatively little impact on how R code is written. There are three challenges to effective use of bquote():
It is only easily used with your code; it is hard to apply it to arbitrary code supplied by a user.
It does not provide an unquote-splice operator that allows you to unquote multiple expressions stored in a list.
It lacks the ability to handle code accompanied by an environment, which is crucial for functions that evaluate code in the context of a data frame, like
subset()and friends.
Base functions that quote an argument use some other technique to allow indirect specification. Base R approaches selectively turn quoting off, rather than using unquoting, so I call them non-quoting techniques.
There are four basic forms seen in base R:
A pair of quoting and non-quoting functions. For example,
$has two arguments, and the second argument is quoted. This is easier to see if you write in prefix form:mtcars$cylis equivalent to`$`(mtcars, cyl). If you want to refer to a variable indirectly, you use[[, as it takes the name of a variable as a string.x <- list(var = 1, y = 2) var <- "y" x$var #> [1] 1 x[[var]] #> [1] 2There are three other quoting functions closely related to
$:subset(),transform(), andwith(). These are seen as wrappers around$only suitable for interactive use so they all have the same non-quoting alternative:[<-/assign()and::/getExportedValue()work similarly to$/[.A pair of quoting and non-quoting arguments. For example,
rm()allows you to provide bare variable names in..., or a character vector of variable names inlist:x <- 1 rm(x) y <- 2 vars <- c("y", "vars") rm(list = vars)data()andsave()work similarly.An argument that controls whether a different argument is quoting or non-quoting. For example, in
library(), thecharacter.onlyargument controls the quoting behaviour of the first argument,package:library(MASS) pkg <- "MASS" library(pkg, character.only = TRUE)demo(),detach(),example(), andrequire()work similarly.Quoting if evaluation fails. For example, the first argument to
help()is non-quoting if it evaluates to a string; if evaluation fails, the first argument is quoted.# Shows help for var help(var) var <- "mean" # Shows help for mean help(var) var <- 10 # Shows help for var help(var)ls(),page(), andmatch.fun()work similarly.
Another important class of quoting functions are the base modelling and plotting functions, which follow the so-called standard non-standard evaluation rules: http://developer.r-project.org/nonstandard-eval.pdf. For example, lm() quotes the weight and subset arguments, and when used with a formula argument, the plotting function quotes the aesthetic arguments (col, cex, etc). Take the following code: we only need col = Species rather than col = iris$Species.
palette(RColorBrewer::brewer.pal(3, "Set1"))
plot(
Sepal.Length ~ Petal.Length,
data = iris,
col = Species,
pch = 20,
cex = 2
)
These functions have no built-in options for indirect specification, but you’ll learn how to simulate unquoting in Section 20.6.