Search code examples
rggplot2ggallyggpairs

How to get R^2 with ggpairs?


How to make ggpairs report the upper corner with R^2 instead of correlation?

library(GGally)    
ggpairs(mtcars[c("mpg", "disp", "hp", "drat", "wt", "qsec")])

enter image description here


Solution

  • I think that you will need to write a custom function, shown below. (One caveat to this approach is that different to correlation the r^2 assumes a dependent variable so this may not be sensible).

    library(GGally) # version 1.5.0
    
    lm_fun <- function(data, mapping, ndp=2, ...){
    
        # Extract the relevant columns as data
        x <- eval_data_col(data, mapping$x)
        y <- eval_data_col(data, mapping$y)
    
        # Calculate the r^2 & format output
        m <- summary(lm(y ~ x))
        lbl <- paste("r^2: ", formatC(m$r.squared, digits=ndp, format="f"))
    
        # Write out label which is centered at x&y position
        ggplot(data=data, mapping=mapping) + 
          annotate("text", x=mean(x, na.rm=TRUE), y=mean(y, na.rm=TRUE), label=lbl, parse=TRUE, ...)+
          theme(panel.grid = element_blank()) 
      }
    
    # Call
    ggpairs(mtcars[c("mpg", "disp", "hp", "drat", "wt", "qsec")], 
            upper=list(continuous=lm_fun))
    

    EDIT: Can you please help to explain how to add a new line into the lbl between r^2 and the value?

    You can use atop by changing the relevant code to either:

    lbl <- substitute(atop(~r^2*':', v), 
                      list(v=formatC(m$r.squared, digits=ndp, format="f")))
    

    or

     v <- formatC(m$r.squared, digits=ndp, format="f")
     lbl <- bquote(atop(~r^2*':', .(v))) 
    

    You then need to tweak the annotate call to correctly parse the label

    annotate("text", x=mean(x, na.rm=TRUE), y=mean(y, na.rm=TRUE), 
              label=deparse(lbl), parse=TRUE, hjust=0, ...)
    

    I added hjust=0 in an attempt to left-align the text but this hasn't quite worked.