Adicionando uma linha de regressão em um ggplot

120

Estou tentando adicionar uma linha de regressão em um ggplot. Tentei primeiro com abline, mas não consegui fazer funcionar. Então eu tentei isso ...

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)

Mas também não está funcionando.

Remi.b
fonte

Respostas:

170

Em geral, para fornecer sua própria fórmula, você deve usar argumentos xe yque corresponderão aos valores fornecidos em ggplot()- neste caso x, serão interpretados como x.plote ycomo y.plot. Mais informações sobre métodos e fórmulas de suavização podem ser encontradas na página de ajuda da função stat_smooth(), pois é a estatística padrão usada pelo geom_smooth().

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

Se você estiver usando os mesmos valores xey fornecidos na ggplot()chamada e precisar traçar a linha de regressão linear, não precisa usar a fórmula interna geom_smooth(), apenas forneça o method="lm".

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

Como acabei de perceber, caso você tenha um modelo ajustado em regressão linear múltipla , a solução mencionada acima não funcionará.

Você deve criar sua linha manualmente como um dataframe que contém os valores previstos para seu dataframe original (no seu caso data).

Seria assim:

# 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 múltiplo

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

Único LR

StefanK
fonte
1
Uma coisa a observar é que a convenção é lm (y ~ x). Eu virei um pouco para uma segunda leitura, pois a variável que você está 'prevendo' está no eixo x. Ótima resposta.
colorlace de
14

A solução óbvia usando geom_abline:

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

Onde data.lmestá um lmobjeto e se data.lm$coefficientsparece com isto:

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

Idêntico na prática é usar stat_functionpara traçar a linha de regressão como uma função de x, fazendo uso de predict:

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

Isso é um pouco menos eficiente, pois, por padrão, os n=101pontos são calculados, mas muito mais flexível, pois traçará uma curva de previsão para qualquer modelo compatível predict, como não linear npregdo pacote np.

Nota: Se você usar scale_x_continuousou, scale_y_continuousalguns valores podem ser cortados e, portanto, geom_smoothpodem não funcionar corretamente. Use coord_cartesianpara aumentar o zoom .

qwr
fonte
2
E para que você nunca se preocupe em ordenar suas fórmulas ou apenas adicionar um, +0você pode usar nomes. data.lm$coefficients[['(Intercept)']]e data.lm$coefficients[['DepDelay']].
Ufos
(Quase) sempre (Intercept)será listado primeiro. Os nomes tornam o código mais claro.
qwr
Acho que esta é a melhor resposta - é a mais versátil.
arranjdavis
4

Eu encontrei essa função em um 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)))
    }`

depois de carregar a função, você pode simplesmente

ggplotRegression(fit)

você também pode ir para ggplotregression( y ~ x + z + Q, data)

Espero que isto ajude.

YellowEagle
fonte
2

Se você quiser ajustar outro tipo de modelo, como uma curva de dose-resposta usando modelos logísticos, você também precisará criar mais pontos de dados com a função de previsão se quiser ter uma linha de regressão mais suave:

ajuste: seu ajuste de uma curva de regressão logística

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