Maybe i am not correct, but it appears to me that there is an undesired space in expressions beginning with a superscript:
df <- data.frame(treatment=as.factor(c("A", "B")), value=c(1,2))
labels <- c(expression(""^14~CH[4]),
expression(""^14~CH[4]~"+"~"SO"[4]^{2-''}))
library(ggplot2)
ggplot(df, aes(treatment, value)) +
geom_bar(stat="identity") +
scale_x_discrete(labels=labels)
I could go to Photoshop to reduce the space between the superscripted 14 and the "C", but maybe there is a way in plotmath? Notice, that this is not happening in the second expression with a superscript in the end.
In expressions, ~ gives you a space between terms. If you don't want a space between terms, you can use *. The end superscript is not preceded by a ~, so no space.
You can also remove most of the quote marks - these are unnecessary except when there are special characters or spaces.
So your expression can become
expression(''^14*CH[4]~+~SO[4]^'2-')
Related
I'm trying to work out how to have subscript letters in an axis label.
dat <- data.frame(x = rnorm(100), y = rnorm(100))
ggplot(dat, aes(x=x,y=y)) +
geom_point() +
labs(y=expression(Blah[1]))
dat <- data.frame(x = rnorm(100), y = rnorm(100))
ggplot(dat, aes(x=x,y=y)) +
geom_point() +
labs(y=expression(Blah[1d]))
The first example works as it's just a number, as soon as you have a character in the square brackets, it fails. Blah[subscript(1d)] is essentially what I need, but I can't work out how to get it to let me have letters in subscript. I have tried variations, including paste().
The following examples provide strange behavior:
labs(y=expression(Blah[12])) # this works
labs(y=expression(Blah[d])) # this works
labs(y=expression(Blah[d1])) # this works
labs(y=expression(Blah[1d])) # this fails
Thoughts?
The reason the last one fails is that the arguments to expression get run through the R parser and an error is returned when they fail the test of whether they could possibly be correct R syntax. The string or token 1d is not a valid R token (or symbol). It would be possible to either break it into valid R tokens and "connect" with non-space operators, backtick it , or use ordinary quotes. I think either is a better way than using paste:
ggplot(dat, aes(x=x,y=y)) +
geom_point() +
labs(y=expression(Blah[1*d]))
ggplot(dat, aes(x=x,y=y)) +
geom_point() +
labs(y=expression(Blah["1d"]))
Tokens (or "names" or "symbols") in R are not supposed to start with digits. So you get around that limitation by either quoting or by separating 1 and d by a non-space separator, the * operator. That "joins" or "ligates" a pure numeric literal with a legal R symbol or token.
To get a percent sign unsubscripted just:
ggplot(dat, aes(x=x,y=y)) +
geom_point() +
labs(y=expression(Blah[1*d]*"%"))
To put parens around the pct-sign:
expression(Blah[1*d]*"(%)")
The % character has special meaning in R parsing, since it signifies the beginning of a user defined infix operator. So using it as a literal requires that it be quoted. The same reasoning requires that "for" and "in" be quoted, because they are in the "reserved words" group for R. There are other reserved words, (but for and in are the ones that trip me up most often.) Type:
?Reserved
And another "trick" is to use quotation marks around digits within italic()if you need them italicized. Unquoted digits do not get italicized inside that function.
Caveats: paste is a plotmath function except it has different semantics than the base::paste function. In particular, it has no 'sep' argument. So you can never get a space between the printed arguments and if you try to put in a non-space item, a single instance will appear after all the other arguments labeled as sep=" ".
paste0 is not a plotmath function and so will not get interpreted but rather will appear "unprocessed" with its unprocessed arguments inside parentheses.
Okay. I swear I didn't post this just to answer it myself, despite how quickly I got it (always the way when you ask a question!)
Here it is:
ggplot(dat, aes(x=x,y=y)) +
geom_point() +
labs(y=expression(Blah[1][d]))
Thought it best to post the answer rather than remove the question as it may help someone else one day.
'Blahs' aside, what I actually wanted was expression(paste("Hb", A[1][c]," (%)",sep=""))
Why paste0() doesn't work here is beyond me.
I'm trying to achieve two things in a ggplot label, being to paste an assigned character variable as well as some text with superscript into the same label. However, I've only been able to do either of those two things but I can't seem to do both at the same time.
name = "Mary"
ggplot() + ylab(expression(paste(name~"BMI"~kg/mm^2))) #this can only do the superscript but not get the name
ggplot() + ylab(paste(name,expression("BMI"~kg/mm^2))) #this can get the name but not the superscript
Any help is appreciated, thanks!
Use bquote
ggplot() + ylab(bquote(.(name)~BMI~kg/mm^2))
reproducible example:
x1<-rnorm(5,5,1)
y1<-rnorm(5,5,1)
d<-data.frame(x1,y1)
ggplot(data=d,aes(x=x1,y=y1))+
geom_point()+
ylab(bquote('y (since year s'* ~ 1^st*' day)'))
I would like to add an apostrophe after "year" and I tried to add '\\'' but it does not work.
There are already several questions asking about superscript:
Subscripts and superscripts "-" or "+" with ggplot2 axis labels? (ionic chemical notation)
How to write chemical formulas in ggplot
ggplot labels adding superscript, how to come out of the superscript?
But I could not find any that combines it with an apostrophe (which is recognized by the superscript expression).
Single quotes ' and double quotes " are usually interchangeable in R code. Get the single quote you want by surrounding the string containing it with double quotes.
library(ggplot2)
x1<-rnorm(5,5,1)
y1<-rnorm(5,5,1)
d<-data.frame(x1,y1)
ggplot(data=d,aes(x=x1,y=y1))+
geom_point()+
ylab(bquote("y (since year's"* ~ 1^st*' day)'))
Created on 2021-01-02 by the reprex package (v0.3.0)
This is almost what I want as a plot heading:
plot(1:10)
ylabs<-c("All","Native","Exotic")
i=1
mtext(bquote("("*.(letters[i])*")"~.(ylabs[i])~"("%~~%italic("H'")*")"),side=3)
But I don't want the space after "(" and before the approx. equal sign. Adding the * separator before the symbol gives an error
mtext(bquote("("*.(letters[i])*")"~.(ylabs[i])~"("*%~~%italic("H'")*")"),side=3)
Error: unexpected SPECIAL in
even though the * separator works in other parts of bquote. I can get the right spacing by including the approx. equal symbol directly
mtext(bquote("("*.(letters[i])*")"~.(ylabs[i])~"("*"≈"~italic("H'")*")"),side=3)
but I would like to know if there's a way to get * to work before the plotmath symbol?
I tried this with expression instead of bquote, but couldn't get it to combine the characters with the indexed objects.
The trick is to put the entire text into a subscript:
plot(1:10)
ylabs<-c("All","Native","Exotic")
i=1
b <- bquote(phantom(0)["("*.(letters[i])*")"~.(ylabs[i])~"(" %~~%italic("H'")*")"])
mtext(b, cex = 2, side=3)
I'm trying to work out how to have subscript letters in an axis label.
dat <- data.frame(x = rnorm(100), y = rnorm(100))
ggplot(dat, aes(x=x,y=y)) +
geom_point() +
labs(y=expression(Blah[1]))
dat <- data.frame(x = rnorm(100), y = rnorm(100))
ggplot(dat, aes(x=x,y=y)) +
geom_point() +
labs(y=expression(Blah[1d]))
The first example works as it's just a number, as soon as you have a character in the square brackets, it fails. Blah[subscript(1d)] is essentially what I need, but I can't work out how to get it to let me have letters in subscript. I have tried variations, including paste().
The following examples provide strange behavior:
labs(y=expression(Blah[12])) # this works
labs(y=expression(Blah[d])) # this works
labs(y=expression(Blah[d1])) # this works
labs(y=expression(Blah[1d])) # this fails
Thoughts?
The reason the last one fails is that the arguments to expression get run through the R parser and an error is returned when they fail the test of whether they could possibly be correct R syntax. The string or token 1d is not a valid R token (or symbol). It would be possible to either break it into valid R tokens and "connect" with non-space operators, backtick it , or use ordinary quotes. I think either is a better way than using paste:
ggplot(dat, aes(x=x,y=y)) +
geom_point() +
labs(y=expression(Blah[1*d]))
ggplot(dat, aes(x=x,y=y)) +
geom_point() +
labs(y=expression(Blah["1d"]))
Tokens (or "names" or "symbols") in R are not supposed to start with digits. So you get around that limitation by either quoting or by separating 1 and d by a non-space separator, the * operator. That "joins" or "ligates" a pure numeric literal with a legal R symbol or token.
To get a percent sign unsubscripted just:
ggplot(dat, aes(x=x,y=y)) +
geom_point() +
labs(y=expression(Blah[1*d]*"%"))
To put parens around the pct-sign:
expression(Blah[1*d]*"(%)")
The % character has special meaning in R parsing, since it signifies the beginning of a user defined infix operator. So using it as a literal requires that it be quoted. The same reasoning requires that "for" and "in" be quoted, because they are in the "reserved words" group for R. There are other reserved words, (but for and in are the ones that trip me up most often.) Type:
?Reserved
And another "trick" is to use quotation marks around digits within italic()if you need them italicized. Unquoted digits do not get italicized inside that function.
Caveats: paste is a plotmath function except it has different semantics than the base::paste function. In particular, it has no 'sep' argument. So you can never get a space between the printed arguments and if you try to put in a non-space item, a single instance will appear after all the other arguments labeled as sep=" ".
paste0 is not a plotmath function and so will not get interpreted but rather will appear "unprocessed" with its unprocessed arguments inside parentheses.
Okay. I swear I didn't post this just to answer it myself, despite how quickly I got it (always the way when you ask a question!)
Here it is:
ggplot(dat, aes(x=x,y=y)) +
geom_point() +
labs(y=expression(Blah[1][d]))
Thought it best to post the answer rather than remove the question as it may help someone else one day.
'Blahs' aside, what I actually wanted was expression(paste("Hb", A[1][c]," (%)",sep=""))
Why paste0() doesn't work here is beyond me.