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!
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:
UPODATE Added (2). Also some improvements and corrections.
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