How to have a new line in a `bquote` expression used with `text`?
Asked Answered
T

3

17

I want to have a new line in my bquote envrionment, how can I do this?

my code:

test<-c(1,2,3,4,4.5,3.5,5.6)
test2<-0.033111111
plot(test,c(1:length(test)))

segments(4,0,4,23,col="red",lwd=2)
text(5, 4.5, labels = bquote(Qua[0.99] == .(round(test2,4))),col="red", cex = 1.4)

And I want to have a new line after the equal sign, so this should give:

VaR_0.99 =

0.03311

and not

    VaR_0.99 = 0.03311

I tried it with lines, but it did not work:

    test<-c(1,2,3,4,4.5,3.5,5.6)
    test2<-0.033111111
    lines<-list(bquote(Qua[0.99] == ),bquote(.(round(test2,4))))
    plot(test,c(1:length(test)))

    segments(4,0,4,23,col="red",lwd=2)
    text(5, 4.5, labels =lines ,col="red", cex = 1.4)
Topaz answered 27/3, 2013 at 15:57 Comment(3)
Have you read this or this?Iveyivie
I tried it with lists, but it did not work! @IveyivieTopaz
You cannot have a trailing "==". Need to put something: either phantom(0)` or " " after the ==.Tailing
T
9

One of the errors was noted above in my comment to the questioner. R expressions get parsed so they need to be syntactically valid. Since "==" is a two-argument function it cannot be the final item in an expression. The phantom function serves as a placeholder that is non-printing. Could also have been an empty character value (""). Since there was no "outside" value that needed to be evaluated, I just used expression() rather than bquote() for the first argument in the expression list.

(Note: that expressions in R behave as lists so that c() succeeds in appending language items to a single element expression and list() is not needed, and in fact was harmful in this situation. There is another subtlety in that bquote does not return an "expression"-classed result but rather a "call". It may need to be wrapped with as.expression if a true "expression" is needed as was the case here. I've seen R savants use an lapply( . , as.expression) to return an expression list in similar situations.)

The other one was more a semantic error than a syntactic one. You need to give an explicit y location for the second bquote expression. Pretty much all of the important arguments of text are vector-capable but there doesn't appear to be implicit up-(or down-)indexing for the y values:

test <- c(1, 2, 3, 4, 4.5, 3.5, 5.6)
test2 <- 0.033111111
lines <- c( expression(Qua[0.99] == phantom(0)) ,
           bquote(.(round(test2,4)))
          )
plot(test,c(1:length(test)))

segments(4,0,4,23,col="red",lwd=2)
text(5, c(4.5, 4), labels =lines ,col="red", cex = 1.4)

enter image description here

I have used the atop suggestion myself in the past, even suggesting it on Rhelp, but I think the approach above generalizes better to three or more expressions and allows more control over positioning. atop also silently reduces font sizes, so if you went the nested atop route for a three expression task, it might need to be atop( atop(..., ...), atop(..., phantom() ) to keep the sizes uniform.

If you include adj=0 in text-call arguments list you get left justification. Tested in the code for the code above.

Tailing answered 27/3, 2013 at 16:24 Comment(0)
I
11

For instance, using atop:

test<-c(1,2,3,4,4.5,3.5,5.6)
test2<-0.033111111
plot(test,c(1:length(test)))

segments(4,0,4,23,col="red",lwd=2)
text(5, 4.5, 
     labels = bquote(atop(Qua[0.99] == phantom(), .(round(test2,4)))),
     col="red", cex = 1.4)

enter image description here

Iveyivie answered 27/3, 2013 at 16:24 Comment(0)
T
9

One of the errors was noted above in my comment to the questioner. R expressions get parsed so they need to be syntactically valid. Since "==" is a two-argument function it cannot be the final item in an expression. The phantom function serves as a placeholder that is non-printing. Could also have been an empty character value (""). Since there was no "outside" value that needed to be evaluated, I just used expression() rather than bquote() for the first argument in the expression list.

(Note: that expressions in R behave as lists so that c() succeeds in appending language items to a single element expression and list() is not needed, and in fact was harmful in this situation. There is another subtlety in that bquote does not return an "expression"-classed result but rather a "call". It may need to be wrapped with as.expression if a true "expression" is needed as was the case here. I've seen R savants use an lapply( . , as.expression) to return an expression list in similar situations.)

The other one was more a semantic error than a syntactic one. You need to give an explicit y location for the second bquote expression. Pretty much all of the important arguments of text are vector-capable but there doesn't appear to be implicit up-(or down-)indexing for the y values:

test <- c(1, 2, 3, 4, 4.5, 3.5, 5.6)
test2 <- 0.033111111
lines <- c( expression(Qua[0.99] == phantom(0)) ,
           bquote(.(round(test2,4)))
          )
plot(test,c(1:length(test)))

segments(4,0,4,23,col="red",lwd=2)
text(5, c(4.5, 4), labels =lines ,col="red", cex = 1.4)

enter image description here

I have used the atop suggestion myself in the past, even suggesting it on Rhelp, but I think the approach above generalizes better to three or more expressions and allows more control over positioning. atop also silently reduces font sizes, so if you went the nested atop route for a three expression task, it might need to be atop( atop(..., ...), atop(..., phantom() ) to keep the sizes uniform.

If you include adj=0 in text-call arguments list you get left justification. Tested in the code for the code above.

Tailing answered 27/3, 2013 at 16:24 Comment(0)
P
0

I wanted this but left aligned. After searching for solutions I ended up using two text() calls set up to put the text 0.25 inch apart and 0.25 in from top regardless of the plot dimensions.

plot(1:100)
r2 <- 40.2
rmse <- 0.6
ll = bquote(paste(italic(R)^2," = ",.(r2),"  RMSE = ",.(rmse)))
val=0.25*diff(par('usr')[3:4])/par('pin')[2]
text(par('usr')[1], par('usr')[4] - val, pos=4, labels=ll)
text(par('usr')[1], par('usr')[4] - 2*val, pos=4, labels="Model A")

Image produced by code

Polish answered 9/4, 2020 at 19:20 Comment(1)
If you add adj=0 to a text-call argument list you get left justification. Tested in the code for the accepted answer.Tailing

© 2022 - 2024 — McMap. All rights reserved.