Show asterisk for significant p values in ggcorrplot

2.3k Views Asked by At

I wanted to ask is it possible to customize the p value representation in ggcorrplot such that instead of having insignificant correlations marked with a cross, the significant p values are marked with an asterisk instead? Which would hopefully look something like so:

enter image description here

2

There are 2 best solutions below

0
On BEST ANSWER

Update: So I decided to look at the source code and tinkered a bit with it to produce the format I wanted to achieve. If you copy the whole code for the ggcorrplot() function, then on line 215 the original code is:

p.mat <- subset(p.mat, p.mat$value > sig.level)

Substitute this with:

p.mat <- subset(p.mat, p.mat$value <= sig.level & p.mat$value != 0)

The != 0 part is assuming you would choose the full correlation plot and is there to prevent the diagonal in the middle from having the asterisk and I believe no p value should practically be 0 so it should be fine.

Then on line 295 I added the position argument inside the function:

# matrix cell glyphs
  if (!is.null(p.mat) & insig == "pch") {
    p <- p + ggplot2::geom_point(
      data = p.mat,
      mapping = ggplot2::aes_string(x = "Var1", y = "Var2"),
      shape = pch,
      size = pch.cex,
      color = pch.col,
      position = position_nudge(x=0.35,y=0.16)
    )
  }

The original would look something like: enter image description here

While the modified one would be something like: enter image description here Of course, depending on visual preference, the nudge can be customized through the x and y argument. Then in the function, just choose pch = 8 (this is the asterisk) and pch.cex = 1 (size of asterisk) and that should basically achieve the objective of showing asterisk for significant correlations instead of showing crosses for insignificant correlations. Hopefully it can be of use in the future!

0
On

Way late to the discussion but I ended up writing some code to add asteriks to corrplots as geom_text labels based on p-vaules that I thought might be helpful. The labels and asteriks behavior are all very customizable.

library(dplyr)
library(ggcorrplot)
library(ggplot2)
library(reshape2)

data(mtcars)

corr = round(cor(mtcars), 1)

# Get p-value matrix
p.df = as.data.frame(ggcorrplot::cor_pmat(mtcars))

# Function to get asteriks
labs.function = function(x){
  case_when(x >= 0.05 ~ "",
            x < 0.05 & x >= 0.01 ~ "*",
            x < 0.01 & x >= 0.001 ~ "**",
            x < 0.001 ~ "***")
}

# Get asteriks matrix based on p-values
p.labs = p.df  %>%                      
  mutate_all(labs.function)

# Reshaping asteriks matrix to match ggcorrplot data output
p.labs$Var1 = as.factor(rownames(p.labs))
p.labs = melt(p.labs, id.vars = "Var1", variable.name = "Var2", value.name = "lab")

# Initial ggcorrplot
cor.plot = ggcorrplot(corr, hc.order = TRUE, type = "lower",
                      lab = TRUE)

# Subsetting asteriks matrix to only those rows within ggcorrplot data
p.labs$in.df = ifelse(is.na(match(paste0(p.labs$Var1, p.labs$Var2), 
                                  paste0(cor.plot[["data"]]$Var1, cor.plot[["data"]]$Var2))),
                      "No", "Yes")

p.labs = select(filter(p.labs, in.df == "Yes"), -in.df)

# Add asteriks to ggcorrplot
cor.plot.labs = cor.plot + 
  geom_text(aes(x = p.labs$Var1, 
                y = p.labs$Var2), 
            label = p.labs$lab, 
            nudge_y = 0.25, 
            size = 5)

This code produces this figure:

ggcorrplot with asteriks