An R bquote example

In this post I provide a simple example on the use of bquote in R. One context in which this function is highly useful is in the generation of a set of multiple well-annotated plots. We may want to plot a series of graphs and perhaps save each to disk as a jpeg for example. Each plot might have a unique title at the top. Let’s say that the titles follow a pattern such as “Plot 1”, “Plot 2”, “Plot 3”, etc. It is easy enough to sequentially plot and/or save your graphics using a for loop, and to use paste to annotate the plots appropriately:

for(i in 1:3) plot(0, 0, type="n", main=paste("Plot ",i,sep=""))

Simple enough. And annotations can become much more complicated and still be automated in a loop without much trouble. However, things become tricky if we want to move beyond simple character strings that can be easily pasted together. Say we wish to add mathematical symbols, which may require the use of expression. For example, to keep things simple, rather than looping over many plots, let’s use text to annotate one plot three times.

z1 <- c("A","B","C")

z2 <- c("high","med","low")

height <- c(0.5,0,-0.5)

plot(0,0,type="n")

Note that we do not actually make use of z1 or z2 yet below. It would be ideal, but that will come later.

text(0, height[1], labels=expression(Y[high] ~ "=" ~ A*x^2), cex=3)

text(0, height[2], labels=expression(Y[med] ~ "=" ~ B*x^2), cex=3)

text(0, height[3], labels=expression(Y[low] ~ "=" ~ C*x^2), cex=3)

Notice the use of expression. Rather than just entering a character string, or pasting multiple strings together, we wrap statements in expression. We pass an expression object to text. Not to deviate from the topic of bquote, as expression is worthy of its own discussion and tutorial on its varied uses, but we can see when plotting this that square brackets put their contents in subscript, the tilde operates as a separator and does not show up on our plot, the equal sign is the only thing quoted here, and the asterisk and caret are, expectedly, interpreted as mathematical expressions or operators, yielding the expected result on our plot.

The problem here is that how we wish to annotate plots as we iterate through a loop seems to preclude our ability to do any looping in the first place. How can we automate and streamline something like this? This will not work:
plot(0,0,type="n")

text(0,height[i],labels=expression(Y[z2[i]] ~ "=" ~ z1[i]*x^2),cex=3)

Ideally, during the ith iteration we would like z1 and z2 to be evaluated. We want to print the ith entry of z1 and z2 on our ith plot. We do not want to literally print "z1[i]", but this is precisely what happens. This is one place where bquote can be extremely helpful. It is short for backquote and essentially wraps quotes around whatever you pass to it. The catch is that anything passed to bquote that is itself wrapped in .() will be evaluated first. Notice below how we use bquote in place of expression and that everything else looks exactly the same as before with the exception that the two things we want to evaluate rather than print literally as displayed, z1[i] and z2[i], are wrapped in .() as required. We now can reproduce our original, desired result shown up above, but without having to hardcode each annotation.
plot(0,0,type="n")

for(i in 1:3) text(0, height[i], labels=bquote(Y[.(z2[i])] ~ "=" ~ .(z1[i])*x^2), cex=3)

The uses of bquote (and expression) go far beyond annotating plots and are useful in conjunction with many other R functions. But this is one clear example of how helpful it can be. The next time you have to write a set of graphics to disk, first and foremost spend some time annotating your graphics well, using symbols, subscripts, superscripts, font sizes, placement, etc. as appropriate. Secondly, don’t hardcode every plot. If you can make your plots sequentially in a loop, use these kinds of techniques to annotate them within the loop as well. It is often the case that people will forgo properly annotating their plots in the interest of expediency (a completely unnecessary tradeoff) or will slow themselves to a crawl doing everything by hand one plot at a time because they are unfamiliar with methods for setting up their annotations in a generic manner so that they can be applied in a more automated fashion.

This entry was posted by Matt Leonawicz.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: