Search code examples
rggplot2purrrggpubrggboxplot

use raw string, instead of escape string, in ggpub::ggboxplot of R


How to use the raw string (such as len/s) in the colnames in ggpubr::ggboxplot in R? It seems due to purrr::map

library(ggpubr)
data("ToothGrowth")
df <- ToothGrowth

colnames(df) <- c("len/s", "supp", "dose%sd")

ggboxplot(df, x = "dose%sd", y = 'len/s',
               color = "dose%sd", palette =c("#00AFBB", "#E7B800", "#FC4E07"),
               add = "jitter", shape = "dose%sd")


with error

Error in `purrr::pmap()`:
ℹ In index: 1.
ℹ With name: len/s.
Caused by error in `purrr::map()`:
ℹ In index: 1.
ℹ With name: x.
Caused by error in `parse()`:
! <text>:1:5: unexpected input
1: dose%sd

---
Backtrace:
  1. ggpubr::ggboxplot(...)
 15. purrr::map(., function(x) parse_expression(x))
 16. purrr:::map_("list", .x, .f, ..., .progress = .progress)
 20. ggpubr (local) .f(.x[[i]], ...)
 21. ggpubr:::parse_expression(x)
 22. base::parse(text = x)

Solution

  • By default, the parse_aes option is set to TRUE.

    > ggpubr_options()
    $ggpubr.parse_aes
    [1] TRUE
    

    We could set the parse_aes options to FALSE and reset after the plotting

    library(ggpubr)
    op <- options(ggpubr.parse_aes = FALSE)
    colnames(df) <- c("len/s", "supp", "dose%sd")
    
    ggboxplot(df, x = "dose%sd", y = 'len/s',
              color = "dose%sd", palette =c("#00AFBB", "#E7B800", "#FC4E07"),
              add = "jitter", shape = "dose%sd")
    
    options(op)
    

    -output

    enter image description here


    ggboxplot calls ggboxplot_core internal function, which calls the ggplot with create_aes where parse = TRUE

    > ggpubr:::ggboxplot_core
    ...
    p <- ggplot(data, create_aes(list(x = x, y = y)))
    ...
    > create_aes
    function (.list, parse = TRUE) 
    {
        if (missing(parse)) {
            parse <- base::getOption("ggpubr.parse_aes", default = TRUE)
        }
        if (parse) {
            return(create_aes.parse(.list))
        }
        else {
            return(create_aes.name(.list))
        }
    }
    

    The create_aes.parse calls the parse_expression whereas the create_aes.name converts to symbol

    > ggpubr:::create_aes.parse
    function (.list) 
    {
        .list <- .list %>% purrr::map(function(x) parse_expression(x))
        do.call(ggplot2::aes, .list)
    }
    
    > ggpubr:::create_aes.name
    function (.list) 
    {
        .list <- .list %>% purrr::map(function(x) to_name(x))
        do.call(ggplot2::aes, .list)
    }
    

    Therefore, it is easier to set the parse_aes to FALSE