subscript in paste()-function

Hi!

I would like to write "µlog = " in the following function with "log" as subscript. I tried it with expression(), but nothing happens.

This is my code:

library(dplyr)

dv <- c(1,5,3,2,4,1,3,4,1,3)
iv <- c(1,2,2,1,3,2,1,3,2,3)

text_labels1 <- group_by(
ivBoxplot %>% drop_na(gleich_entf_kat, iv, dv),
  iv
) %>% summarise(
  textlabel = paste(
    "n =", format(n(), big.mark = " ",justify = "left"),
    "\n",
     expression("µ"[log]), sprintf('%.2f',mean(dv),justify = "left")
  ),
  y=200
)

text_labels1

I hope, I was clear enough in explaining my problem.

I think you meant to pass log as a string, not a variable. Try running this piece of code for example:

plot(1:10, main = expression("µ"["log"]))

Hm, now it looks very weird:

Here my new code:

library(ggplot2)
library(tidyverse)

dv <- c(1.,0.5,0.9,2,4,1,0.3,4,0.1,3)
dv_log <- log10(dv)
iv <- c(1,2,2,1,3,2,1,3,2,3)
dat <- data.frame(dv,dv_log,iv)
dat <- mutate(dat,dv_kat = cut(dv,breaks =  c(0,0.3,0.5,0.7,0.9,1.12,1.43,2.01,3.31,105),labels = c("5","4","3","2","1","2","3","4","5")))

text_labels1 <- group_by(
dat %>% drop_na(dv_kat, iv, dv),
  iv
) %>% summarise(
  textlabel = paste(
    "n =", format(n(), big.mark = " ",justify = "left"),
    "\n",
    "µ[log]"," = ", sprintf('%.2f',mean(dv_log),justify = "left")
  ),
  y=200
)

# plotten
ggplot(dat,mapping = aes(
  x = as.numeric(iv),
  y = dv
)) +
  geom_text(
    data = text_labels1,
    aes(label = textlabel,color=NULL,
        y=y),show.legend = FALSE,size=2.5,parse = TRUE
  ) +
  geom_hline(yintercept = 1e+00,linetype="dotted")+ # horizontale Linie zeigt die 100%ige Übereinstimmung der Zugangszeiten an
  geom_jitter(position=position_jitter(0.25),aes(color = factor(dv_kat)), alpha=0.6)+
  stat_boxplot(aes(group=iv),geom ='errorbar',width=0.25)+
  geom_boxplot(aes(group=iv),outlier.color = "transparent",fill="transparent") +
  scale_color_manual(values = c("red4", "red3", "orange", "green3", "green4"), labels = c("sehr schlecht", "schlecht", "mäßig", "gut", "sehr gut"),guide = guide_legend(shape = c(rep(16, 7), NA, NA))) +
  scale_x_continuous(breaks = 1:3, name = "IV", labels = c("1", "2", "3")) +
  scale_y_continuous(trans='log10', limits = c(0.006,200))+
  scale_fill_manual(breaks = 1:3, name = "IV", labels = c("1", "2", "3")) +
  labs(x = "IV",
       y = "XYZ-Fakt [log]",
       color = "XYZ:") + 
  theme_bw()+
  theme(legend.position = "bottom",legend.background = element_rect(color = "black",fill = "transparent"),legend.key.size = unit(0.3,"cm"))

Oh I missed that for the y axis, so you can ignore my final comment in my previous answer, but the rest of the code should work. If you use exactly this code, does it not work on your computer? It does look as if you didn't use the option parse = TRUE.

library(tidyverse)

dv <- c(1.,0.5,0.9,2,4,1,0.3,4,0.1,3)
dv_log <- log10(dv)
iv <- c(1,2,2,1,3,2,1,3,2,3)
dat <- data.frame(dv,dv_log,iv)
dat <- mutate(dat,dv_kat = cut(dv,breaks =  c(0,0.3,0.5,0.7,0.9,1.12,1.43,2.01,3.31,105),labels = c("5","4","3","2","1","2","3","4","5")))

text_labels1 <- group_by(
  dat %>% drop_na(dv_kat, iv, dv),
  iv
) %>% summarise(
  textlabel = paste(
    "atop(n ==", format(n(), big.mark = " ",justify = "left"),
    ",µ[log]"," == ", sprintf('%.2f',mean(dv_log),justify = "left")
    ,")"),
  y=100
)

# plotten
ggplot(dat,mapping = aes(
  x = as.numeric(iv),
  y = dv
)) +
  geom_text(
    data = text_labels1,
    aes(label = textlabel,color=NULL,
        y=y),show.legend = FALSE,size=4,parse = TRUE
  ) +
  geom_hline(yintercept = 1e+00,linetype="dotted")+ # horizontale Linie zeigt die 100%ige Übereinstimmung der Zugangszeiten an
  geom_jitter(position=position_jitter(0.25),aes(color = factor(dv_kat)), alpha=0.6)+
  stat_boxplot(aes(group=iv),geom ='errorbar',width=0.25)+
  geom_boxplot(aes(group=iv),outlier.color = "transparent",fill="transparent") +
  scale_color_manual(values = c("red4", "red3", "orange", "green3", "green4"), labels = c("sehr schlecht", "schlecht", "mäßig", "gut", "sehr gut"),guide = guide_legend(shape = c(rep(16, 7), NA, NA))) +
  scale_x_continuous(breaks = 1:3, name = "IV", labels = c("1", "2", "3")) +
  scale_y_continuous(trans='log10', limits = c(0.006,200))+
  scale_fill_manual(breaks = 1:3, name = "IV", labels = c("1", "2", "3")) +
  labs(x = "IV",
       y = "XYZ-Fakt [log]",
       color = "XYZ:") + 
  theme_bw()+
  theme(legend.position = "bottom",legend.background = element_rect(color = "black",fill = "transparent"),legend.key.size = unit(0.3,"cm"))

3 Likes

Thank you! This looks good!

Sorry, that I write again. Is there any possibility to combine this with a third column of a text label?

library(tidyverse)

dv <- c(1.,0.5,0.9,2,4,1,0.3,4,0.1,3)
dv_log <- log10(dv)
iv <- c(1,2,2,1,3,2,1,3,2,3)
dat <- data.frame(dv,dv_log,iv)
dat <- mutate(dat,dv_kat = cut(dv, breaks =  c(0,0.3,0.5,0.7,0.9,1.12,1.43,2.01,3.31,105), labels = c("5","4","3","2","1","2","3","4","5")))

text_labels1 <- group_by(
dat %>% drop_na(dv_kat, iv, dv),
  iv
) %>% summarise(
  textlabel = paste(
    "n =", format(n(), big.mark = " ",justify = "left"),
    "\n",
    "µ[log]"," = ", sprintf('%.2f',mean(dv_log),justify = "left"),
    "\n",
    "µ"," = ", sprintf('%.2f',mean(dv),justify = "left")
  ),
  y=200
)

This is how it should look like:
grafik

A third line, you mean?

I think the best solution is to use several text commands, for example:

text_labels1 <- group_by(
  dat %>% drop_na(dv_kat, iv, dv),
  iv
) %>% summarise(
  textlabel_top = paste("n ==", format(n(), big.mark = " ",justify = "left")),
  textlabel_mid = paste("µ[log]"," == ", sprintf('%.2f',mean(dv_log),justify = "left")),
  textlabel_bot = paste("µ == ", sprintf('%f', 0.85)),
  y_top = 200,
  y_mid = 120,
  y_bot = 80
)

# plotten
ggplot(dat,mapping = aes(
  x = as.numeric(iv),
  y = dv
)) +
  geom_text(
    data = text_labels1,
    aes(label = textlabel_top,color=NULL,
        y=y_top),show.legend = FALSE,size=2.5,parse = TRUE
  ) +
  geom_text(
    data = text_labels1,
    aes(label = textlabel_mid,
        color=NULL,
        y=y_mid),show.legend = FALSE,size=2.5,parse = TRUE
  ) +
  geom_text(
    data = text_labels1,
    aes(label = textlabel_bot,
        color=NULL,
        y=y_bot),show.legend = FALSE,size=2.5,parse = TRUE
  ) +
  geom_hline(etc...

Another approach could be to nest two atop, but it's not an ideal solution (because you have different font size), so that text_labels1 contains this:

"atop(n == 3,atop(µlog == -0.07,µ == 0.85))"

Something like that should do:

textlabel = paste(
    "atop(n ==", format(n(), big.mark = " ",justify = "left"),
    ",atop(µ[log]"," == ", sprintf('%.2f',mean(dv_log),justify = "left")
    ,",µ == ", sprintf('%f', 0.85),"))")

Yes, I meant line :woman_facepalming:

Thanks a lot. Your first solution is perfect. I also tried to nest two atop before asking again, but it didn't want to work.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.

Oh, I see. I believe in that case you need to set parse = TRUE inside geom_text() to parse the expressions for the text labels. See this SO post for an example.

1 Like

Yes, it's meant to be a string. Your code works, but the µlog isn't my title, it's just a label, which is placed over each boxplot:

Here is my code again for the full plot:

library(dplyr)
library(ggplot2)
dv <- c(1.,0.5,0.9,2,4,1,0.3,4,0.1,3)
dv_log <- log10(dv)
iv <- c(1,2,2,1,3,2,1,3,2,3)
dat <- data.frame(dv,dv_log,iv)
dat <- mutate(dat,dv_kat = cut(dv,breaks =  c(0,0.3,0.5,0.7,0.9,1.12,1.43,2.01,3.31,105),labels = c("5","4","3","2","1","2","3","4","5")))

text_labels1 <- group_by(
dat %>% drop_na(dv_kat, iv, dv),
  iv
) %>% summarise(
  textlabel = paste(
    "n =", format(n(), big.mark = " ",justify = "left"),
    "\n",
     expression("µ"['log'])," = ", sprintf('%.2f',mean(dv_log),justify = "left")
  ),
  y=200
)

# plotten
ggplot(dat,mapping = aes(
  x = as.numeric(iv),
  y = dv
)) +
  geom_text(
    data = text_labels1,
    aes(label = textlabel,color=NULL,
        y=y),show.legend = FALSE,size=2.5
  ) +
  geom_hline(yintercept = 1e+00,linetype="dotted")+ # horizontale Linie zeigt die 100%ige Übereinstimmung der Zugangszeiten an
  geom_jitter(position=position_jitter(0.25),aes(color = factor(dv_kat)), alpha=0.6)+
  stat_boxplot(aes(group=iv),geom ='errorbar',width=0.25)+
  geom_boxplot(aes(group=iv),outlier.color = "transparent",fill="transparent") +
  scale_color_manual(values = c("red4", "red3", "orange", "green3", "green4"), labels = c("sehr schlecht", "schlecht", "mäßig", "gut", "sehr gut"),guide = guide_legend(shape = c(rep(16, 7), NA, NA))) +
  scale_x_continuous(breaks = 1:3, name = "IV", labels = c("1", "2", "3")) +
  scale_y_continuous(trans='log10', limits = c(0.006,200))+
  scale_fill_manual(breaks = 1:3, name = "IV", labels = c("1", "2", "3")) +
  labs(x = "IV",
       y = "XYZ-Fakt [log]",
       color = "XYZ:") + 
  theme_bw()+
  theme(legend.position = "bottom",legend.background = element_rect(color = "black",fill = "transparent"),legend.key.size = unit(0.3,"cm"))

Hope, I made it clearer now.

When the labels get parsed, the whole string has to be a compatible plotmath expression. So, you can't use a=b which gets replaced by =(a,b), instead you have to use ==. Similarly a space has to be annotated by ~ or *. But the big problem is that you can't directly include newlines with \n, you can replace that with atop. So this should work:

text_labels1 <- group_by(
  dat %>% drop_na(dv_kat, iv, dv),
  iv
) %>% summarise(
  textlabel = paste(
    "atop(n ==", format(n(), big.mark = " ",justify = "left"),
    ",µ[log]"," == ", sprintf('%.2f',mean(dv_log),justify = "left")
  ,")"),
  y=200
)

Note that you may need to change the size of the text back to something bigger, to change the text y to something lower (e.g. 100 instead of 200), and in labs() you also need to convert y to an expression, e.g.

labs(x = "IV",
     y = str2expression("XYZ-Fakt [log]"),
     color = "XYZ:") + 
1 Like

Sorry, that I wasn't clear enough: I wanted to change the label above the boxplot, not the y-axis label, where I need to keep the format of "XYZ-Faktor [log]" in which nothing is meant to be a subscript.

As I already said, the subscript should be in the text labels above each of the boxplots. The label above the first boxplot (1) should look like that:
grafik

With the sprintf-funciton, I get the values which should be printed after "n = " (number of observations) and "grafik" (mean of the values of the according group).

Maybe the subscript could work in sprintf(), but I didn't find any expression for that.

This is how the graph looks now, which isn't quite what I intended to do:

Hope, I made it clearer now.