19.5 Non-quoting
Base R has one function that implements quasiquotation: bquote()
. It uses .()
for unquoting:
bquote((x + y + z))
xyz <-bquote(-.(xyz) / 2)
#> -(x + y + z)/2
bquote()
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$cyl
is 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.list(var = 1, y = 2) x <- "y" var <- $var x#> [1] 1 x[[var]]#> [1] 2
There 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
:1 x <-rm(x) 2 y <- c("y", "vars") 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.only
argument controls the quoting behaviour of the first argument,package
:library(MASS) "MASS" pkg <-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) "mean" var <-# Shows help for mean help(var) 10 var <-# 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(
~ Petal.Length,
Sepal.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.