Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bquote: How to include an expression saved as a string object?

My goal is to annotate a plot with the slope of a best-fit line and label the units of the slope, where the label is saved as a separate string object. I'm having trouble figuring out how to get bquote() to convert a string object into an expression, and combine it with other evaluated statements.

A demonstration:

# example data:
x <- c(1:20)                   # x units: time
y <-  x * rnorm(20, 10, 2)     # y units: length per time

unit.label <- "L%.%T^-2"       # label for slope of best fit line 
lm1 <- summary(lm(y ~ x))

plot(y ~ x)

The problem occurs when I try to annotate the plot. I can get bquote() to display the slope:

text(median(x), min(y), bquote(slope: .(round(lm1$coefficients[2], 2))) )

I can also get bquote() to show the slope's units:

plot(y ~ x)
text(median(x), min(y), bquote(.(parse(text = unit.label))) )

But I'm unable to combine the label and the slope into a single bquote() statement:

plot(y ~ x)
text(median(x), min(y), bquote(slope: .(round(lm1$coefficients[2], 2)) 
.(parse(text = unit.label))) ) 
# Error: unexpected symbol in "text(median(x), min(y), bquote(slope: 
# .(round(lm1$coefficients[2], 2)) ."

Using paste(), the unit label appears along with the slope, but the label isn't read as an expression:

plot(y ~ x)
text(median(x), min(y), bquote(slope: .(paste(round(lm1$coefficients[2], 2), 
as.expression(unit.label))))
)

Where am I going wrong? Is it a simple syntax problem in my bquote command? Thanks for any suggestions!

like image 201
Troy Avatar asked Jun 09 '14 23:06

Troy


1 Answers

1) parse char string Create the character string desired (ensuring that it represents an expressoin that is syntactically valid in R) and then parse it. Here main_s is the character string:

fm <- lm(y ~ x)

main_s <- paste("slope:", round(coef(fm)[2], 2), "~", unit.label)
plot(0, main = parse(text = main_s))

The statement setting main_s could alternately be replaced with the following sprintf statement which is arguably more readable:

main_s <- sprintf("slope: %.2f ~ %s", coef(fm)[2], unit.label)

2) bquote The above is probably the most straight-forward way to handle this but to use bquote try this where unit.label_c is a call object and fm is as defined above:

unit.label_c <- parse(text = unit.label)[[1]]
plot(0, main = bquote(slope: .(round(coef(fm)[2], 2)) ~ .(unit.label_c)))

In either case we get this:

screenshot

UPODATE Added (2). Also some improvements and corrections.

like image 166
G. Grothendieck Avatar answered Nov 11 '22 23:11

G. Grothendieck