Ajout d'une ligne de régression sur un ggplot

121

J'essaye fort d'ajouter une ligne de régression sur un ggplot. J'ai d'abord essayé avec abline mais je n'ai pas réussi à le faire fonctionner. Puis j'ai essayé ceci ...

data = data.frame(x.plot=rep(seq(1,5),10),y.plot=rnorm(50))
ggplot(data,aes(x.plot,y.plot))+stat_summary(fun.data=mean_cl_normal) +
   geom_smooth(method='lm',formula=data$y.plot~data$x.plot)

Mais cela ne fonctionne pas non plus.

Remi.b
la source

Réponses:

171

En général, pour fournir votre propre formule , vous devez utiliser des arguments xet yqui correspondent aux valeurs que vous avez données ggplot()- dans ce cas , xsera interprétée comme x.plotet yque y.plot. Vous trouverez plus d'informations sur les méthodes et les formules de lissage dans la page d'aide de la fonction, stat_smooth()car c'est la statistique par défaut utilisée par geom_smooth().

ggplot(data,aes(x.plot, y.plot)) +
  stat_summary(fun.data=mean_cl_normal) + 
  geom_smooth(method='lm', formula= y~x)

Si vous utilisez les mêmes valeurs x et y que celles que vous avez fournies dans l' ggplot()appel et que vous devez tracer une ligne de régression linéaire, vous n'avez pas besoin d'utiliser la formule à l'intérieur geom_smooth(), il vous suffit de fournir le method="lm".

ggplot(data,aes(x.plot, y.plot)) +
  stat_summary(fun.data= mean_cl_normal) + 
  geom_smooth(method='lm')
Didzis Elferts
la source
47

Comme je viens de le comprendre, au cas où vous auriez un modèle ajusté sur une régression linéaire multiple , la solution mentionnée ci-dessus ne fonctionnera pas.

Vous devez créer votre ligne manuellement en tant que dataframe qui contient les valeurs prévues pour votre dataframe d'origine (dans votre cas data).

Cela ressemblerait à ceci:

# read dataset
df = mtcars

# create multiple linear model
lm_fit <- lm(mpg ~ cyl + hp, data=df)
summary(lm_fit)

# save predictions of the model in the new data frame 
# together with variable you want to plot against
predicted_df <- data.frame(mpg_pred = predict(lm_fit, df), hp=df$hp)

# this is the predicted line of multiple linear regression
ggplot(data = df, aes(x = mpg, y = hp)) + 
  geom_point(color='blue') +
  geom_line(color='red',data = predicted_df, aes(x=mpg_pred, y=hp))

LR multiple

# this is predicted line comparing only chosen variables
ggplot(data = df, aes(x = mpg, y = hp)) + 
  geom_point(color='blue') +
  geom_smooth(method = "lm", se = FALSE)

LR unique

StefanK
la source
1
Une chose à surveiller est la convention est lm (y ~ x). Je me suis un peu retourné pour une deuxième lecture car la variable que vous «prédisez» est sur l'axe des x. Excellente réponse cependant.
colorlace
14

La solution évidente en utilisant geom_abline:

geom_abline(slope = data.lm$coefficients[2], intercept = data.lm$coefficients[1])

data.lmest un lmobjet et data.lm$coefficientsressemble à quelque chose comme ceci:

data.lm$coefficients
(Intercept)    DepDelay 
  -2.006045    1.025109 

La même chose en pratique consiste stat_functionà tracer la droite de régression en fonction de x, en utilisant predict:

stat_function(fun = function(x) predict(data.lm, newdata = data.frame(DepDelay=x)))

C'est un peu moins efficace car par défaut les n=101points sont calculés, mais beaucoup plus flexible car il tracera une courbe de prédiction pour tout modèle qui prend en charge predict, comme non linéaire à npregpartir du package np.

Remarque: Si vous utilisez scale_x_continuousou scale_y_continuouscertaines valeurs peuvent être coupées et donc geom_smoothne pas fonctionner correctement. Utilisez coord_cartesianplutôt pour zoomer .

qwr
la source
2
Et vous ne vous inquiétez donc jamais de la commande de vos formules ou simplement de l'ajout d'un nom que +0vous pouvez utiliser. data.lm$coefficients[['(Intercept)']]et data.lm$coefficients[['DepDelay']].
Ufos
(Presque) (Intercept)sera toujours répertorié en premier. Les noms rendent le code plus clair.
qwr
Je pense que c'est la meilleure réponse - c'est la plus polyvalente.
arranjdavis
4

J'ai trouvé cette fonction sur un blog

 ggplotRegression <- function (fit) {

    `require(ggplot2)

    ggplot(fit$model, aes_string(x = names(fit$model)[2], y = names(fit$model)[1])) + 
      geom_point() +
      stat_smooth(method = "lm", col = "red") +
      labs(title = paste("Adj R2 = ",signif(summary(fit)$adj.r.squared, 5),
                         "Intercept =",signif(fit$coef[[1]],5 ),
                         " Slope =",signif(fit$coef[[2]], 5),
                         " P =",signif(summary(fit)$coef[2,4], 5)))
    }`

une fois que vous avez chargé la fonction, vous pouvez simplement

ggplotRegression(fit)

vous pouvez aussi opter pour ggplotregression( y ~ x + z + Q, data)

J'espère que cela t'aides.

Aigle jaune
la source
2

Si vous souhaitez ajuster d'autres types de modèles, comme une courbe dose-réponse à l'aide de modèles logistiques, vous devrez également créer plus de points de données avec la fonction prédire si vous souhaitez avoir une ligne de régression plus lisse:

fit: votre ajustement d'une courbe de régression logistique

#Create a range of doses:
mm <- data.frame(DOSE = seq(0, max(data$DOSE), length.out = 100))
#Create a new data frame for ggplot using predict and your range of new 
#doses:
fit.ggplot=data.frame(y=predict(fit, newdata=mm),x=mm$DOSE)

ggplot(data=data,aes(x=log10(DOSE),y=log(viability)))+geom_point()+
geom_line(data=fit.ggplot,aes(x=log10(x),y=log(y)))
user3436882
la source