Search code examples
rggplot2rstatix

Question about the functions `get_test_label` and `get_pwc_label` from the `rstatix` package


I have recently become familiar with the rstatix package. Below is an example code using functions from this package.

library(tidyverse)
library(rstatix)
library(ggpubr)

set.seed(1111)
n=100
df = tibble(
  x1 = rnorm(n, 0, 1.1),
  x2 = rnorm(n, 0.2, .1),
  x3 = rnorm(n, -.2, .2),
  x4 = rnorm(n, 0, 2),
) %>% pivot_longer(x1:x4)
df

pwc = df %>%
  pairwise_t_test(value~name, paired = TRUE,
                  p.adjust.method = "bonferroni") %>%
  add_xy_position(x = "name") %>%
  mutate(name=group1,
         lab = paste(p, " - ", p.adj.signif))
res.test = df %>% anova_test(value~name)

df %>% ggplot(aes(name, value))+
  geom_boxplot(alpha=0.6)+
  stat_pvalue_manual(pwc, step.increase=0.05, label = "lab")+
  labs(title = get_test_label(res.test, detailed = TRUE),
       subtitle = get_pwc_label(pwc))

However, I noticed that functions like get_test_label or get_pwc_label do not return text, but commands to prepare the text.

For example, calling get_test_label(res.test, detailed = TRUE) gives this:

paste("Anova, ", italic("F"), "(3,396)", " = ", 
    "5.26, ", italic("p"), " = ", "0.001", 
    paste(", ", eta["g"]^2, " = ", 0.04), "")

In turn, calling get_pwc_label(pwc) will result in:

paste("pwc: ", bold(c(t_test = "T test")), "; p.adjust: ", 
    bold("Bonferroni"))

Now my question, basically two questions.

  1. What could be the reason these functions do not return text but commands?
  2. How to make your own function that returns similar commands.

Solution

  • R's graphics devices use the syntax defined in ?plotmath to distinguish between literal and formatted text. A basic feature of this syntax is that strings define literal text while functions define operations on text, such as juxtaposition and formatting (changing fonts, adding diacritics, getting whitespace right in mathematical formulae, etc.). What you are seeing, then, are unevaluated compositions of functions and strings defining formatted text. These are typically called plotmath expressions.

    I could provide you with a basic example showing how different expressions translate to graphical output, but there is an excellent demo built into R: just run demo("plotmath") in an interactive R session and follow the prompts.

    Functions that you can use to create expressions like the ones you are seeing include quote, substitute, bquote, and str2lang. You would probably use one of these to format, e.g., a plot title. Here is how I would use each function to generate the expression paste("Michaelis constant: ", italic("K")["M"], " = ", 0.015).

    quote(
      paste("Michaelis constant: ", italic("K")["M"], " = ", 0.015)
    )
    
    substitute(
      paste("Michaelis constant: ", italic(sym)[sub], " = ", val),
      list(sym = "K", sub = "M", val = 0.015)
    )
    
    sym <- "K"
    sub <- "M"
    val <- 0.015
    bquote(
      paste("Michaelis constant: ", italic(.(sym))[.(sub)], " = ", .(val))
    )
    
    str2lang(
      'paste("Michaelis constant: ", italic("K")["M"], " = ", 0.015)'
    )
    

    The differences are subtle, so it could be worth browsing each function's help page and running the examples there.

    Functions that you can use to create expression vectors include expression and str2expression. You would use one of these to format one or more labels at once, e.g., when defining axis tick labels. Here is how I would use each function to format labels for ticks at increasing powers of 10:

    expression(10^0, 10^1, 10^2, 10^3, 10^4, 10^5)
    str2expression(paste0(10, "^", 0:5))
    

    Finally, here is a fun plot putting everything together:

    plot.new()
    plot.window(c(0, 1), c(1, 100000), log = "y")
    box()
    title(main = quote(paste("Michaelis constant: ", italic("K")["M"], " = ", 0.015)))
    axis(side = 2, at = 10^(0:5), labels = str2expression(paste0(10, "^", 0:5)), las = 1)
    text(x = seq(0, 1, by = 0.2), y = 10^(0:5), labels = str2expression(sprintf('%s("%s")', c("plain", "bold", "italic", "bolditalic", "symbol", "underline"), month.abb[1:6])))
    

    For even more examples, take a look at ?plotmath.