df <- data.frame(a=c(1,2,3,4,5,6),
b=c("x1","x2","y1","y2","w1","w2"),
c=runif(6),
d=c(1,1,2,2,3,3))
p <- ggplot(aes(x=b, y=c), data=df) +
geom_bar(stat="identity") +
facet_grid(~d, scales="free_x")
I'd like to use expression (or any other function) in order to create subscripts for each label. I tried this:
new_labels <- c(expression("x[1]"),expression("x[2]"),expression("y[1]"),expression("y[2]"),expression("w[1]"),expression("w[2]"))
p + scale_x_discrete(labels=new_labels)
and this
new_labels2 <- c("x[1]","x[2]","y[1]","y[2]","w[1]","w[2]")
p + scale_x_discrete(labels=function(new_labels2) expression(new_labels2))
but none of these solutions gave me the intended result.
Also how can I change the bar colors to be the same in all facets?
I thought p + scale_fill_manual(values=c("green","red")) would work, but it has no effect.
You can provide a function to the labels argument of scale_x_discrete to generate the expressions as strings and then parse the strings to have them interpreted as expressions. In the example below I've also added fill=grepl("1", b) which will map column b to the fill aesthetic based on whether there's a 1 or not in the value of b. This mapping is necessary to generate fill colours that can then be set with scale_fill_manual.
p = ggplot(aes(x=b, y=c, fill=grepl("1", b)), data=df) +
geom_bar(stat="identity") +
facet_grid(~d, scales="free_x") +
guides(fill=FALSE) +
scale_x_discrete(labels=function(l) parse(text=gsub("(.)([0-9])", "\\1[\\2]", l)))
p

For illustration, below is what the gsub function is doing to generate the strings before they're parsed as expressions (basically just doing programmatically what you hard-coded in your question):
p <- ggplot(aes(x=b, y=c, fill=grepl("1", b)), data=df) +
geom_bar(stat="identity") +
facet_grid(~d, scales="free_x") +
guides(fill=FALSE) +
scale_x_discrete(labels=function(l) gsub("(.)([0-9])", "\\1[\\2]", l))
p

The gsub function uses regular expressions to do the substitutions. If you're not familiar with regular expressions, another, perhaps less opaque way to code this would be:
function(l) paste0(substr(l,1,1), "[", substr(l,2,2), "]")
If you want to set your own fill colours, you could do:
p + scale_fill_manual(values=c("green","red"))
In reference to the question in your comment: You can create a dummy grouping variable as follows:
library(tidyverse)
p <- df %>%
group_by(b.grp = substr(b, 1, 1)) %>%
mutate(grp.val = 1:n()) %>%
ggplot(aes(x=b, y=c, fill=factor(grp.val))) +
geom_bar(stat="identity") +
facet_grid(~d, scales="free_x") +
guides(fill=FALSE) +
scale_x_discrete(labels=function(l) parse(text=gsub("(.)(.)", "\\1[\\2]", l)))
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