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.

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

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


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 .


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.


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)))
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.