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:
Show asterisk for significant p values in ggcorrplot
2.3k Views Asked by Jeff238 At
2
There are 2 best solutions below
0

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:
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:
The original would look something like:
While the modified one would be something like:
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!