What is the best (easiest) approach to add neatly to a ggplot plot the regression equation, the R2, and the p-value (for the equation)? Ideally it should be compatible with groups and faceting.
This first plot with has the regression equation plus the r2 and p-value by group using ggpubr, but they are not aligned? Am I missing something? Could they be included as one string?
library(ggplot)
library(ggpubr)
ggplot(mtcars, aes(x = wt, y = mpg, group = cyl))+
geom_smooth(method="lm")+
geom_point()+
stat_regline_equation()+
stat_cor(aes(label = paste(..rr.label.., ..p.label.., sep = "*`,`~")),
label.x.npc = "centre")
Here is an option with ggpmisc, that does some odd placement.
EDIT Odd placement was caused by geom=text
, which I've commented out to provide better placement, and added `label.x = "right" to stop overplotting. We still have misalignemnt as per ggpubr, due to the superscript issue flagged by @dc37
#https://stackoverflow.com/a/37708832/4927395
library(ggpmisc)
ggplot(mtcars, aes(x = wt, y = mpg, group = cyl))+
geom_smooth(method="lm")+
geom_point()+
stat_poly_eq(formula = "y~x",
aes(label = paste(..eq.label.., ..rr.label.., sep = "*`,`~")),
parse = TRUE)+
stat_fit_glance(method = 'lm',
method.args = list(formula = "y~x"),
#geom = 'text',
aes(label = paste("P-value = ", signif(..p.value.., digits = 4), sep = "")))
I did find a good solution for bringing the relevant stats together, but that requires creating the regression outside ggplot, and a pile of string manipulation fluff - is this as easy as it gets? Also, it doesn't (as currently coded) deal to the grouping, and wouldn't deal with facetting.
#https://stackoverflow.com/a/51974753/4927395
#Solution as one string, equation, R2 and p-value
lm_eqn <- function(df, y, x){
formula = as.formula(sprintf('%s ~ %s', y, x))
m <- lm(formula, data=df);
# formating the values into a summary string to print out
# ~ give some space, but equal size and comma need to be quoted
eq <- substitute(italic(target) == a + b %.% italic(input)*","~~italic(r)^2~"="~r2*","~~p~"="~italic(pvalue),
list(target = y,
input = x,
a = format(as.vector(coef(m)[1]), digits = 2),
b = format(as.vector(coef(m)[2]), digits = 2),
r2 = format(summary(m)$r.squared, digits = 3),
# getting the pvalue is painful
pvalue = format(summary(m)$coefficients[2,'Pr(>|t|)'], digits=1)
)
)
as.character(as.expression(eq));
}
ggplot(mtcars, aes(x = wt, y = mpg, group=cyl))+
geom_point() +
geom_text(x=3,y=30,label=lm_eqn(mtcars, 'wt','mpg'),color='red',parse=T) +
geom_smooth(method='lm')
See Question&Answers more detail:
os