I'm plotting a histogram in R and I want to include a $\bar{X}$ expression in the main argument of hist and combine it with the value of a dynamically calculated variable average.
x <- rnorm(100, 1, 1)
average <- mean(x)
hist(x, main=paste("Average $\bar{X}=", average))
That SO doesn't work and I spent hours trying to get it working with an expression statement or a substitute statement, both of which I dont find a case in the examples where the value of a variable is substituted in the text.
This solution uses * to paste text and expressions and uses substitute to replace 'average' with the calculated value.
hist(x, main = substitute("Average "*bar(x)*" = "*average, list(average=average)))
Try:
hist(x, main=bquote(Average~bar(X)==.(average) )
bquote's main use is to "import-and-evaluate" named values from the global (or enclosing) environment(s) into an expression which would otherwise not be evaluating its tokens. You could add spaces to make the expression more readable but the parser ignores them:
hist(x, main=bquote( Average ~ bar(X) == .( average ) )
If you need extra spaces use multiple tilde's: ~~~
It's rather interesting to look at the code for bquote (easy since it's not hidden):
bquote
Related
I wish to label the x-axis of a volcano plot I made using EnhancedVolcano as "Log2(B/A)" where 2 is a subscript, and B/A is a character vector I define as X.axis. Xlab is one of the arguments of EnhancedVolcano function.
I tried:
X.axis <- "(B/A)"
log2 <- expression(~Log[2])
xlab = paste(log2,X.axis)
Result was ~Log[2](B/A)
I also tried:
log2 <- expression(~Log[2]~X.axis)
xlab = log2
This gave Log2 X.axis.
What am I doing wrong?
X.axis <- "B/A"
ggplot(mtcars, aes(mpg, disp)) +
geom_point() +
scale_x_continuous(name = bquote(Log[2] * bgroup("(", .(X.axis), ")" )))
Alternatively, you can do a more-apparent fraction, though it is easier (given what little I know of your available variables) to do it statically:
ggplot(mtcars, aes(mpg, disp)) +
geom_point() +
scale_x_continuous(name = bquote(Log[2] * bgroup("(", over(B, A), ")" )))
I admit to not knowing all of the differences between using expression(.) and bquote(.) for labels and such. They return different class objects (expression and call, respectively) but can be used interchangeably in many cases, but the latter supports (for instance) value replacement (the .(X.axis) above), something I find very useful.
Explanation of my comments to r2evans:
The advantage of bquote over expression is that its embedded, accessory function cryptically named "." allows one to access values of named objects that exist in the calling frame. The expression function never evaluates the symbols or tokens that are placed in its list of arguments. The disadvantage of bquote is that it will not accept multiple arguments. To return multiple arguments as an expression list/vector with bquote, one needs to deploy it with an sapply or lapply call.
The bquotewith. function-combo solved the puzzle that was facing the OP who wanted the value of X.axis but instead only got its name in the printed result of the expression call. Keeping the various levels of meaning straight is a challenge to new users of R. The introduction of the tidyverse solved that challenge in some settings by collapsing the layers to some extent, but probably delays acquisition of understanding ordinary "standard evaluation" in R.
The tilde operator inside an argument to expression is handled by the plotmath engine as a space. Notice that r2evans did not use a tilde but rather used an asterisk "*", because it is also a valid separator to delimit the tokenization process by the R parser, but it leaves no "space" in the plotmath output. The `tilde operator has many, diverse uses in R. It can be a function returning a formula, a spacing operator in a plotmath expression or a couple of different connector un a tidyverse evaluation
I am trying to write an equation like "R^2=0.00575" in the legend, and the number 0.00575 can be embedded in the legend automatically. Here is an example.
set.seed(100)
x=rnorm(100)
y=1:100
fit=lm(y~x)
R_squared=format(summary(fit)$r.squared,digits = 3)
plot(x,y,type="l")
legend("topleft",legend =expression(R^{2}~"="~R_squared),bty = "n")
As the figure shows, the variable "R_squared" is not embedded in the equation. Is there any solution? Thanks.
For this task I think it is best to do parse(text=sprintf(...)). You can code the R language syntax into the string literal to be parsed into an R expression using parse(), and use sprintf() format specifications to embed any numeric or string values that are stored in variables into the expression.
set.seed(100L);
x <- rnorm(100L);
y <- 1:100;
fit <- lm(y~x);
R_squared <- format(summary(fit)$r.squared,digits=3L);
plot(x,y,type='l');
legend('topleft',legend=parse(text=sprintf('paste(R^2,\' = %s\')',R_squared)),bty='n');
An alternative syntax that leverages the fact that == is plotted as a single equal sign:
legend('topleft',legend=parse(text=sprintf('R^2 == %s',R_squared)),bty='n');
See the plotmath documentation.
You can also use bquote:
set.seed(100L);
x <- rnorm(100L);
y <- 1:100;
fit <- lm(y~x);
R_squared <- format(summary(fit)$r.squared,digits=3L);
plot(x,y,type='l');
legend('topleft',legend=bquote(R^{2} ~ "=" ~ .(R_squared)),bty='n');
More information on partial substitution of expressions with bquote can be found here, which defines the function as:
An analogue of the LISP backquote macro. bquote quotes its argument
except that terms wrapped in .() are evaluated in the specified where
environment.
I want to add a label with mathematical notations and a number reference to my plot. I tried the expression function and the paste function, but I failed to include what I want to write in my plot.
Here is a easy version of my question:
plot(NA,xlim = c(0, 5), ylim = c(0,5))
a = 5
At point (1,1), I want to add a label γ=5 on the plot. Here is what I tried:
text(1,1,expression(paste(gamma, "=", a)))
But the plot shows that γ=a.
I am wondering how I can include a number reference in the combination of expression and paste function.
Thank you!
Good day!
I am not that familiar to R so I'd be glad to get a little help.
Assume I have the following minimal example:
test <- c(10,20,40,80,80)
avg <- mean(test)
avg <- format(avg,digits=2)
plot(test, xlab="x", ylab="y", pch = 4)
legend("topleft", legend= c("Average: ", avg))
I'd like to write x̄ instead of "average" - wonder if this is event possible as it's not a regular symbol - merely a combination of two (letter plus overline).
The other thing I'd like to get rid of is the line break after the word "Average (see arrow in graphic below):
There are two issues here. The first is that this is handled using ?plotmath in R. The operator you are looking for is bar(). This is not a function but markup that plotmath understands.
The second is that you need an expression in which avg is converted to its value. You need an expression because that is what plotmath works with. There are several solutions to this problem, but the one I use below is bquote(). You provide it an expression and anything wrapped in .( ) will be converted its value by evaluating the thing inside the .( ).
Here is your code and a suitably modified legend() call:
test <- c(10,20,40,80,80)
avg <- mean(test)
avg <- format(avg,digits=2)
plot(test, xlab="x", ylab="y", pch = 4)
legend("topleft", legend = bquote(bar(x)*":" ~ .(avg)))
Do note that this will insert exactly what is in avg. You may need to do
avg <- round(avg)
or some other formatting fix to get something nice and presentable.
Say, I have a variable rv which has some numerical value. Now, I want to plot the value of this variable on a base plot but preceded by a nicely formatted symbol e.g., r subscript m, using expression. To write on the plot I use mtext.
However, what I get is either the value of the variable, but no nicely formatted symbol (left annotation), or a nicely formatted symbol, but not the value of the variable, but the variable name...
I tried to play around with eval, but didn't get what I wanted. Here is my code:
plot(1:10, rep(10,10), ylim=c(0,12))
rv <- 0.43
#left annotation:
mtext(paste(expression(italic(r[M])), " = ", rv), side = 1, line = -1.5, adj = 0.1)
#right annotation:
mtext(expression(paste(italic(r[M]), " = ", rv)), side = 1, line = -1.5, adj = 0.9)
This is the result:
How do i get both, nice format and value of the variable? Thanks.
btw: I know that I can get it, if I use two times mtext and play around with adj and stuff. But I would really like to get it in one call or without playing around with the position of two annotations.
The bquote function will create an expression and alow substitution of values using .(var) syntax. for your case do something like:
text( 5,1, bquote( italic(r[M]) == .(rv) ) )
Just combine what you have and plot two pieces, joined by using adj:
R> plot(1:10, rep(10,10), ylim=c(0,12))
R> text(2,12, expression(paste(italic(r[M]))), adj=1)
R> text(2,12, paste("=", rv), adj=0)