Search code examples
rcorrelationggallyggpairs

Adding p-value and r-value in separate lines in correlogram using ggpairs in R


I am trying to plot a correlation matrix using the ggpairs function in the GGally R package. By default it displays the correlation coefficient in digits and adds stars next to it to represent the p-value. However I would like to have the correlation coefficient and the p-value both in digits upto two decimals, one below the other.

e.g. r = 0.84
     p = 0.01

Here's the data:

> dput(df)
structure(list(A = c(7.4434, 8.1305, 8.8554, 7.6841, 6.9656, 
8.2225, 7.7836, 6.8234, 8.6265, 8.3475, 8.1828), B = c(5.4939, 
6.8466, 6.796, 6.2022, 5.0935, 7.0202, 5.4479, 4.9634, 6.6522, 
6.451, 7.3865), C = c(10.1219, 10.863, 10.6, 10.7336, 9.8241, 
10.6802, 10.2687, 9.2575, 10.581, 10.7611, 10.6775), D = c(6.3524, 
4.5371, 3.4795, 3.8661, 7.5537, 3.7855, 4.3958, 8.1428, 3.7458, 
4.1419, 3.6338)), row.names = c(NA, -11L), class = c("tbl_df", 
"tbl", "data.frame"))

and this is what I have tried so far:

library(GGally) 

ggpairs(data = df,
    upper = list(continuous = wrap("cor", method = "pearson", size = 6, color = "black")), 
    lower = list(continuous = wrap("smooth", color = "firebrick")),
    diag = list(continuous = wrap("densityDiag", fill = "slategray3")))

enter image description here


Solution

  • One option to achieve your desired result would be to use a customized function for which I adapted the source code of ggally_cor:

    library(GGally)
    
    my_ggally_cor <- function(data,
                              mapping,
                              ...) {
      args <- list(...)
      ggally_statistic(
        data,
        mapping,
        title = NULL,
        sep = NULL,
        text_fn = function(x, y) {
          corObj <- stats::cor.test(x, y,
            method = args$method,
            use = args$use
          )
          cor_est <- as.numeric(corObj$estimate)
          p_est <- as.numeric(corObj$p.value)
    
          cor_txt <- formatC(cor_est, digits = args$digits, format = "f")
          p_txt <- formatC(p_est, digits = args$digits, format = "f")
          paste0("r = ", cor_txt, "\n", "p = ", p_txt)
        }
      )
    }
    
    ggpairs(
      data = df,
      upper = list(continuous = wrap(
        my_ggally_cor,
        method = "pearson", digits = 2,
        size = 6, color = "black"
      )),
      lower = list(continuous = wrap("smooth", color = "firebrick")),
      diag = list(continuous = wrap("densityDiag", fill = "slategray3"))
    )