Aggiunta di una linea di regressione su un ggplot


120

Sto cercando di aggiungere una linea di regressione su un ggplot. Ho provato per la prima volta con l'abline ma non sono riuscito a farlo funzionare. Poi ho provato questo ...

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)

Ma non funziona neanche.

Risposte:


170

In generale, per fornire la tua formula dovresti usare argomenti xe yche corrisponderanno ai valori che hai fornito ggplot()- in questo caso xsaranno interpretati come x.plote ycome y.plot. Ulteriori informazioni sui metodi e sulla formula di smoothing sono disponibili nella pagina della guida della funzione stat_smooth()in quanto è la statistica predefinita utilizzata da geom_smooth().

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

Se stai usando gli stessi valori xey che hai fornito nella ggplot()chiamata e devi tracciare la linea di regressione lineare, non è necessario usare la formula all'interno geom_smooth(), basta fornire il method="lm".

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

47

Come ho appena capito, nel caso in cui tu abbia un modello adattato alla regressione lineare multipla , la soluzione sopra menzionata non funzionerà.

Devi creare la tua linea manualmente come un dataframe che contiene i valori previsti per il tuo dataframe originale (nel tuo caso data).

Sarebbe simile a questo:

# 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 multiplo

# 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 singolo


1
Una cosa a cui prestare attenzione è che la convenzione è lm (y ~ x). Mi sono girato un po 'per una seconda lettura poiché la variabile che stai "prevedendo" è sull'asse x. Ottima risposta però.
colorlace

14

La soluzione ovvia utilizzando geom_abline:

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

Dov'è data.lmun lmoggetto e data.lm$coefficientsassomiglia a questo:

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

Identico in pratica è usare stat_functionper tracciare la retta di regressione in funzione di x, facendo uso di predict:

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

Questo è un po 'meno efficiente poiché per impostazione predefinita n=101vengono calcolati i punti, ma molto più flessibile poiché traccerà una curva di previsione per qualsiasi modello che supporti predict, come non lineare npregdal pacchetto np.

Nota: se si utilizza scale_x_continuouso scale_y_continuousalcuni valori potrebbero essere interrotti e quindi geom_smoothpotrebbero non funzionare correttamente. Utilizzare coord_cartesianinvece per ingrandire .


2
E così non ti preoccupi mai di ordinare le tue formule o semplicemente di aggiungere un nome +0che puoi usare. data.lm$coefficients[['(Intercept)']]e data.lm$coefficients[['DepDelay']].
UFO

(Quasi) (Intercept)sarà sempre elencato per primo. I nomi rendono il codice più chiaro.
qwr

Penso che questa sia la risposta migliore: è la più versatile.
arranjdavis

4

Ho trovato questa funzione su 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)))
    }`

una volta caricata la funzione potresti semplicemente

ggplotRegression(fit)

puoi anche andare per ggplotregression( y ~ x + z + Q, data)

Spero che questo ti aiuti.


2

Se vuoi adattare altri tipi di modelli, come una curva dose-risposta utilizzando modelli logistici, dovresti anche creare più punti dati con la funzione di previsione se vuoi avere una linea di regressione più uniforme:

fit: il tuo adattamento di una curva di regressione logistica

#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)))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.