const-ae / ggsignif

Easily add significance brackets to your ggplots
https://const-ae.github.io/ggsignif/
GNU General Public License v3.0
593 stars 43 forks source link

feature request: allowing parsing #64

Closed IndrajeetPatil closed 5 years ago

IndrajeetPatil commented 5 years ago

ggplot and some of its extensions (e.g, ggrepel) allow the labels to be parsed into expressions and displayed as described in plotmath. But, as far as I understand ggsignif, this is currently possible?

Will you consider supporting it? Thanks.


# setup
library(tidyverse)
library(ggsignif)

# creating a dataframe 
(df <- tibble::tribble(
  ~x, ~lab,
  1, "p < 0.001",
  2, paste("list(~italic(p)<=", "0.001", ")", sep = "")
))
#> # A tibble: 2 x 2
#>       x lab                    
#>   <dbl> <chr>                  
#> 1     1 p < 0.001              
#> 2     2 list(~italic(p)<=0.001)

# ggplot supports parsing
ggplot(mtcars, aes(am, wt)) + geom_point() + 
  labs(x = parse(text = df$lab[2]))


# ggsignif doesn't
ggplot(mpg, aes(class, hwy)) +
  geom_boxplot() +
  geom_signif(comparisons = list(c("compact", "pickup")), 
              annotations = parse(text = df$lab[2]))
#> Warning: Computation failed in `stat_signif()`:
#> cannot coerce class '"expression"' to a data.frame

Created on 2019-07-02 by the reprex package (v0.3.0)

Session info ``` r devtools::session_info() #> - Session info ---------------------------------------------------------- #> setting value #> version R version 3.6.0 (2019-04-26) #> os Windows 10 x64 #> system x86_64, mingw32 #> ui RTerm #> language (EN) #> collate English_United States.1252 #> ctype English_United States.1252 #> tz Europe/London #> date 2019-07-02 #> #> - Packages -------------------------------------------------------------- #> package * version date lib #> assertthat 0.2.1 2019-03-21 [1] #> backports 1.1.4 2019-04-10 [1] #> broom 0.5.2.9001 2019-06-26 [1] #> callr 3.2.0 2019-03-15 [1] #> cellranger 1.1.0 2016-07-27 [1] #> cli 1.1.0 2019-03-19 [1] #> colorspace 1.4-1 2019-03-18 [1] #> crayon 1.3.4 2017-09-16 [1] #> curl 3.3 2019-01-10 [1] #> desc 1.2.0 2019-04-03 [1] #> devtools 2.0.2 2019-04-08 [1] #> digest 0.6.19 2019-05-20 [1] #> dplyr * 0.8.2 2019-06-29 [1] #> evaluate 0.14 2019-05-28 [1] #> fansi 0.4.0 2018-11-05 [1] #> forcats * 0.4.0 2019-02-17 [1] #> fs 1.3.1 2019-05-06 [1] #> generics 0.0.2 2019-03-05 [1] #> ggplot2 * 3.2.0.9000 2019-06-05 [1] #> ggsignif * 0.5.0 2019-02-20 [1] #> glue 1.3.1 2019-03-12 [1] #> gtable 0.3.0 2019-03-25 [1] #> haven 2.1.0 2019-02-19 [1] #> highr 0.8 2019-03-20 [1] #> hms 0.4.2 2018-03-10 [1] #> htmltools 0.3.6 2017-04-28 [1] #> httr 1.4.0 2018-12-11 [1] #> jsonlite 1.6 2018-12-07 [1] #> knitr 1.23 2019-05-18 [1] #> labeling 0.3 2014-08-23 [1] #> lazyeval 0.2.2 2019-03-15 [1] #> lubridate 1.7.4 2018-04-11 [1] #> magrittr 1.5 2014-11-22 [1] #> memoise 1.1.0 2017-04-21 [1] #> mime 0.7 2019-06-11 [1] #> modelr 0.1.4 2019-02-18 [1] #> munsell 0.5.0 2018-06-12 [1] #> pillar 1.4.2 2019-06-29 [1] #> pkgbuild 1.0.3 2019-03-20 [1] #> pkgconfig 2.0.2 2018-08-16 [1] #> pkgload 1.0.2 2018-10-29 [1] #> prettyunits 1.0.2 2015-07-13 [1] #> processx 3.3.1 2019-05-08 [1] #> ps 1.3.0 2018-12-21 [1] #> purrr * 0.3.2 2019-03-15 [1] #> R6 2.4.0 2019-02-14 [1] #> Rcpp 1.0.1 2019-03-17 [1] #> readr * 1.3.1 2018-12-21 [1] #> readxl 1.3.1 2019-03-13 [1] #> remotes 2.1.0 2019-06-24 [1] #> rlang 0.4.0 2019-06-25 [1] #> rmarkdown 1.13 2019-05-22 [1] #> rprojroot 1.3-2 2018-01-03 [1] #> rvest 0.3.4 2019-05-15 [1] #> scales 1.0.0 2018-08-09 [1] #> sessioninfo 1.1.1 2018-11-05 [1] #> stringi 1.4.3 2019-03-12 [1] #> stringr * 1.4.0 2019-02-10 [1] #> testthat 2.1.1 2019-04-23 [1] #> tibble * 2.1.3 2019-06-06 [1] #> tidyr * 0.8.3 2019-03-01 [1] #> tidyselect 0.2.5 2018-10-11 [1] #> tidyverse * 1.2.1 2017-11-14 [1] #> usethis 1.5.0.9000 2019-06-24 [1] #> utf8 1.1.4 2018-05-24 [1] #> vctrs 0.1.0 2018-11-29 [1] #> withr 2.1.2 2018-03-15 [1] #> xfun 0.8 2019-06-25 [1] #> xml2 1.2.0 2018-01-24 [1] #> yaml 2.2.0 2018-07-25 [1] #> zeallot 0.1.0 2018-01-28 [1] #> source #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> local #> CRAN (R 3.6.0) #> CRAN (R 3.5.1) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.5.1) #> CRAN (R 3.6.0) #> Github (r-lib/desc@c860e7b) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> Github (brodieG/fansi@ab11e9c) #> CRAN (R 3.5.2) #> CRAN (R 3.6.0) #> Github (r-lib/generics@c15ac43) #> Github (tidyverse/ggplot2@b560662) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.5.1) #> CRAN (R 3.5.1) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.5.0) #> CRAN (R 3.6.0) #> CRAN (R 3.5.1) #> CRAN (R 3.5.1) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.5.1) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.5.1) #> CRAN (R 3.6.0) #> CRAN (R 3.5.1) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.5.1) #> CRAN (R 3.6.0) #> CRAN (R 3.5.1) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.6.0) #> CRAN (R 3.5.1) #> CRAN (R 3.6.0) #> Github (r-lib/usethis@d4eabb9) #> CRAN (R 3.5.1) #> CRAN (R 3.6.0) #> CRAN (R 3.5.1) #> CRAN (R 3.6.0) #> CRAN (R 3.5.1) #> CRAN (R 3.5.1) #> CRAN (R 3.5.1) #> #> [1] C:/Users/inp099/Documents/R/win-library/3.6 #> [2] C:/Program Files/R/R-3.6.0/library ```
const-ae commented 5 years ago

Hi Indrajeet, thank you for the suggestion, this would definitely be a useful addition. I will try and see how difficult it is to add it, when I find some time. However, if anyone (or you) would be interested in giving it a try, I would also be very happy to accept a pull request. Best, Constantin

cloudbroken commented 5 years ago

Agree this would be a useful feature. In the meantime this is a hacked together function which produces scientific notation for p values with ggsignif.

  library(ggplot2)
  library(ggsignif)

  # function to format a numeric p-value in scientific notation
  # max_pd parameter refers to max decimal places before switching to scientific notation. Otherwise the full decimal is displayed.
  # p-values are given to one significant digit

  pform <- function(p, max_dp = 4) {
    # map the superscript versions of numbers (obtained from https://en.wikipedia.org/wiki/Unicode_subscripts_and_superscripts)
    ucmap <- c("0" = "\u2070",
               "1" = "\u00B9",
               "2" = "\u00B2",
               "3" = "\u00B3",
               "4" = "\u2074",
               "5" = "\u2075",
               "6" = "\u2076",
               "7" = "\u2077",
               "8" = "\u2078",
               "9" = "\u2079",
               "-" = "\u207B")

    pe <- formatC(signif(p,1), digits = 0, format = "e")

    pv <- unlist(strsplit(pe, split = "e"))

    if(abs(as.numeric(pv[2])) > max_dp) {

      pv2 <- as.character(as.numeric(pv[2]))

      pv2v <- unlist(strsplit(pv2, split = ""))

      ps <- paste(ucmap[pv2v], sep = "", collapse = "")

      paste(pv[1],"x10", ps, collapse = "", sep = "")

    } else {
      formatC(signif(p,1), digits = max_dp, format = "f", drop0trailing = T)
    }
  }

  # test
  ggplot(mpg, aes(class, hwy)) +
    geom_boxplot() +
    geom_signif(comparisons = list(c("compact", "pickup")), 
                map_signif_level = pform)

image

Otherwise thank you for a supremely useful package!

const-ae commented 5 years ago

Hi, I finally got around to implemented the parsing of plotmath expressions.

Note that you have to call the function with annotations set to a string that is internally parsed, if parse=TRUE. This follows the example of geom_text() and is different from labs().

# setup
library(tidyverse)
library(ggsignif)

# creating a dataframe 
(df <- tibble::tribble(
  ~x, ~lab,
  1, "p < 0.001",
  2, paste("list(~italic(p)<=", "0.001", ")", sep = "")
))
#> # A tibble: 2 x 2
#>       x lab                    
#>   <dbl> <chr>                  
#> 1     1 p < 0.001              
#> 2     2 list(~italic(p)<=0.001)

# ggplot supports parsing
ggplot(mtcars, aes(as.character(am), wt)) + 
  geom_point() + 
  geom_signif(annotations = df$lab[2], comparisons = list(c("0", "1"))) +
  labs(x = parse(text = df$lab[2]))


# ggplot supports parsing
ggplot(mtcars, aes(as.character(am), wt)) + 
  geom_point() + 
  geom_signif(annotations = df$lab[2], comparisons = list(c("0", "1")),
              parse=TRUE) +
  labs(x = parse(text = df$lab[2]))

Created on 2019-08-05 by the reprex package (v0.3.0)

It would be great if you could test if this solves your issue. If so, I would try to push an updated version to CRAN in the coming days.

Best, Constantin

IndrajeetPatil commented 5 years ago

Dear Constantin,

Thank you so much for implementing this! I can confirm that this is working as expected.

const-ae commented 5 years ago

The update version is now on CRAN :)