0

How can I italicize t , and p values using stat_pvalue_manual() , from ggpubr() in the boxplot below?

  • The plot is:

my pic

  • The code is:
##
library(tidyverse) 
library(rstatix)   # Identify outliers and Stats Summary function
library(ggpubr)    # Plot correlation
library(RVAideMemoire) # Shapiro test on groups 
library(glue) # Round p value in the plots 
##
df %>%
      ggplot(., aes(x = TEST, y = VALUE)) +
      stat_boxplot(geom = "errorbar",
                   width = 0.15) +
      geom_boxplot(aes(fill = TEST), outlier.colour = "yellow", outlier.shape = 18,
                   outlier.size= 2, notch = F) +
      stat_pvalue_manual(df %>%
                           t_test(VALUE ~ TEST, paired = T) %>%
                           add_xy_position(),
                         label = "t ({df}) = {round(statistic, 2)}, p = {round(p, 3)}") 
         
               
               
               #stat_pvalue_manual(df %>%
                #                    wilcox_test(VALUE ~ TEST, paired = T) %>%
                 #                   add_xy_position(),
                  #                label = "W = {round(statistic, 2)}, p = {round(p, 3)}") +

QUESTIONS

  • 1: I've seen with annotate() here, but I couldn't find a solution for stat_pvalue_manual(). How can I italicize t and p ? Help would be much appreciated. Thanks!

  • 2: "bonus": Does anybody know how to make stat_pvalue_manual() display the convention p < 0.05* , p < 0.01 ** and p<0.001***?

  • data:

structure(list(ID = c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L, 
6L, 6L, 7L, 7L, 8L, 8L, 9L, 9L, 10L, 10L, 11L, 11L, 12L, 12L, 
13L, 13L, 14L, 14L, 15L, 15L, 16L, 16L, 17L, 17L, 18L, 18L, 19L, 
19L, 20L, 20L, 21L, 21L, 22L, 22L, 23L, 23L, 24L, 24L, 25L, 25L, 
26L, 26L, 27L, 27L, 28L, 28L, 29L, 29L, 30L, 30L, 31L, 31L), 
    TEST = c("TEST1", "TEST2", "TEST1", "TEST2", "TEST1", "TEST2", 
    "TEST1", "TEST2", "TEST1", "TEST2", "TEST1", "TEST2", "TEST1", 
    "TEST2", "TEST1", "TEST2", "TEST1", "TEST2", "TEST1", "TEST2", 
    "TEST1", "TEST2", "TEST1", "TEST2", "TEST1", "TEST2", "TEST1", 
    "TEST2", "TEST1", "TEST2", "TEST1", "TEST2", "TEST1", "TEST2", 
    "TEST1", "TEST2", "TEST1", "TEST2", "TEST1", "TEST2", "TEST1", 
    "TEST2", "TEST1", "TEST2", "TEST1", "TEST2", "TEST1", "TEST2", 
    "TEST1", "TEST2", "TEST1", "TEST2", "TEST1", "TEST2", "TEST1", 
    "TEST2", "TEST1", "TEST2", "TEST1", "TEST2", "TEST1", "TEST2"
    ), VALUE = c(70, 73, 66, 140, 59, 59, 61, 70, 73, 107, 90, 
    91, 59, 95, 82, 133, 60, 80, 40, 45, 77, 96, 49, 50, 61, 
    56, 92, 120, 56, 110, 56, 110, 68, 83, 87, 113, 87, 114, 
    87, 134, 79, 57, 45, 65, 83, 71, 50, 52, 44, 56, 95, 138, 
    82, 126, 134, 118, 42, 72, 70, 87, 84, 112)), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -62L))
  • EDIT: How to apply the solution with tests inside a list?

library(stringr)

dfPaired <- df
dfLong <- df %>% pivot_wider(names_from = TEST, values_from = VALUE)


### Create list outside of the loop
    
    PairedtestResults <- list()
    
    ### run loop

    for (bb in seq(from = 1, to = 4, by = 2)) {
      
      
      ## Create vars
      
      PairedVar1 <- dfPaired[bb+1]     #G1 Variables
      PairednVar1 <- names(PairedVar1)
      dfPaired$PairedVar1Unlist <- unlist(PairedVar1)
      
      PairedVar2 <- dfPaired[bb+2]     #G2 Variables
      PairednVar2 <- names(PairedVar2)
      dfPaired$PairedVar2Unlist <- unlist(PairedVar2)
      
      ### store and perform tests:
      
      PairedtestResults[[bb]] <-  t.test(dfPairedFiltered$PairedVar1Unlist, dfPairedFiltered$PairedVar2Unlist,
                                         paired = T, data =  dfPaired, exact = F)
      
      PairedtestResults[[bb]]$data.name <- str_glue("{PairednVar1} and {PairednVar2}")


## wide to long to plot it:


### wide to long to plot data and extract eff size:
  
  dfplot <- dfPairedFiltered %>% 
    dplyr::select(ID, PairedVar1Unlist, PairedVar2Unlist) %>%  
    pivot_longer(c(PairedVar1Unlist, PairedVar2Unlist),
                 names_to = "TEST",
                 values_to = "VALUE") %>% 
    mutate(LANGUAGE = case_when(TEST == "PairedVar1Unlist" ~ "GROUP1",
                                TEST == "PairedVar2Unlist" ~  "GROUP2")) %>% 
    mutate(TEST = as.factor(TEST),
           TEST = fct_relevel(TEST, c("GROUP1", "GROUP2"))) %>% 
    dplyr::select(ID, VALUE, TEST)
      
    }

  df %>%
    ggplot(., aes(x = TEST, y = VALUE)) +
    stat_boxplot(geom = "errorbar",
                 width = 0.15) +
    geom_boxplot(aes(fill = TEST), outlier.colour = "yellow", outlier.shape = 18,
                 outlier.size= 2, notch = F) +
        geom_bracket(xmin = "TEST1", xmax = "TEST2",
                     y.position = 250,
                     position = "identity",
                    label =  glue::glue(
                       paste0(
                         "~italic(t) ({PairedtestResults[[bb]][['parameter']]}) == {round(PairedtestResults[[bb]][['statistic']], 2)}*','",
                         "~italic(p) == '{rd(PairedtestResults[[bb]][['p.value']], digits = 3)}'*','"
                       )
                     ),
                     type = "expression",
                     inherit.aes = F,
                    data = dfLong)
  • Updated data:
structure(list(ID = 1:31, TEST1 = c(70, 66, 59, 61, 73, 90, 59, 
82, 60, 40, 77, 49, 61, 92, 56, 56, 68, 87, 87, 87, 79, 45, 83, 
50, 44, 95, 82, 134, 42, 70, 84), TEST2 = c(73, 140, 59, 70, 
107, 91, 95, 133, 80, 45, 96, 50, 56, 120, 110, 110, 83, 113, 
114, 134, 57, 65, 71, 52, 56, 138, 126, 118, 72, 87, 112), TEST3 = c(34, 
51, 67, 33, 56, 37, 38, 46, 47, 45, 45, 95, 39, 47, 32, 42, 36, 
45, 39, 48, 35, 38, 60, 72, 31, 49, 60, 30, 27, 56, 38), TEST4 = c(40, 
45, 46, 30, 72, 26, 22, 26, 27, 38, 21, 65, 19, 25, 32, 66, 50, 
29, 16, 35, 40, 34, 40, 54, 28, 43, 48, 32, 36, 52, 23)), row.names = c(NA, 
-31L), class = c("tbl_df", "tbl", "data.frame"))
Larissa Cury
  • 806
  • 2
  • 11

1 Answers1

1

One option to get the italics would be to switch to geom_bracket which using type="expression" allows to use a ?plotmath expression. Concerning your second question this could for example achieved by formatting the p value using scales::label_pvalue() and using rstatix ::add_significance()

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

dat_t <- df %>%
  t_test(VALUE ~ TEST, paired = T) %>%
  add_xy_position() |> 
  add_significance()

df %>%
  ggplot(., aes(x = TEST, y = VALUE)) +
  stat_boxplot(
    geom = "errorbar",
    width = 0.15
  ) +
  geom_boxplot(aes(fill = TEST),
    outlier.colour = "yellow", outlier.shape = 18,
    outlier.size = 2, notch = F
  ) +
  geom_bracket(
    data = dat_t,
    aes(
      y.position = y.position + 5,
      label = glue::glue(
        paste0(
          "~italic(t) ({df}) == {round(statistic, 2)}*','",
          "~italic(p) ~ '{scales::label_pvalue(prefix = c('< ', ' ', '> '))(p)}{p.signif}'"
        )
      )
    ),
    type = "expression",
    inherit.aes = FALSE
  )

enter image description here

stefan
  • 90,330
  • 6
  • 25
  • 51
  • thank you very much, @stefan! However, my tests are actually inside a list of tests (I'm using a loop to perform multiple tests at the same it)... I cannot extract the tests from the list using this code...I'll edit the post with the code – Larissa Cury May 18 '23 at 16:44
  • I could work a bit around it, I'll add in the edited code, but it's still not ideal I believe – Larissa Cury May 18 '23 at 17:13
  • I guess I could come around it! However, I cannot apply APA's rules to it, can you help ? https://stackoverflow.com/questions/76283338/how-to-apply-apas-rules-to-p-values-inside-geom-bracket – Larissa Cury May 18 '23 at 18:26
  • I tried to apply ```scales::label_pvalue(prefix = c('< ', ' ', '> '))``` but it isn't working, I cannot apply it extracting the results from the list – Larissa Cury May 18 '23 at 18:45