Добавление линии регрессии на график ggplot

121

Я очень стараюсь добавить линию регрессии на графике ggplot. Сначала я попробовал аблайн, но мне не удалось заставить его работать. Потом я попробовал это ...

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)

Но это тоже не работает.

Remi.b
источник

Ответы:

171

В целом, чтобы обеспечить свою собственную формулу , которую вы должны использовать аргументы xи yкоторые будут соответствовать значениям, предусмотренным в ggplot()- в этом случае xбудет интерпретироваться как x.plotи yв y.plot. Более подробную информацию о методах сглаживания и формуле вы можете найти на странице справки функции, stat_smooth()поскольку это статистика, используемая по умолчанию geom_smooth().

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

Если вы используете те же значения x и y, которые вы указали в ggplot()вызове, и вам нужно построить линию линейной регрессии, вам не нужно использовать внутреннюю формулу geom_smooth(), просто укажите method="lm".

ggplot(data,aes(x.plot, y.plot)) +
  stat_summary(fun.data= mean_cl_normal) + 
  geom_smooth(method='lm')
Дидзис Эльфертс
источник
47

Как я только что понял, если у вас есть модель, подходящая для множественной линейной регрессии , вышеупомянутое решение не сработает.

Вы должны создать свою строку вручную как фрейм данных, который содержит предсказанные значения для вашего исходного фрейма данных (в вашем случае data).

Это выглядело бы так:

# 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

# 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

StefanK
источник
1
Одна вещь, на которую следует обратить внимание, - это соглашение lm (y ~ x). Я немного повернулся для второго чтения, так как переменная, которую вы «прогнозируете», находится на оси x. Хотя отличный ответ.
colorlace
14

Очевидное решение с использованием geom_abline:

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

Где data.lmнаходится lmобъект, и data.lm$coefficientsвыглядит примерно так:

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

На практике идентичным является stat_functionпостроение линии регрессии как функции от x с использованием predict:

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

Это немного менее эффективно, поскольку по умолчанию n=101вычисляются точки, но гораздо более гибко, поскольку строит кривую прогноза для любой поддерживаемой модели predict, например нелинейной npregиз пакета np.

Примечание. Если вы используете scale_x_continuousили, scale_y_continuousнекоторые значения могут быть обрезаны и, следовательно, geom_smoothмогут работать некорректно. Вместо этого используйте coord_cartesianдля увеличения .

qwr
источник
2
И поэтому вам не нужно беспокоиться об упорядочивании формул или просто добавлении +0имен. data.lm$coefficients[['(Intercept)']]и data.lm$coefficients[['DepDelay']].
Ufos
(Почти) всегда (Intercept)будет отображаться первым. Имена делают код более понятным.
qwr
Думаю, это лучший ответ - самый универсальный.
Arranjdavis
4

Я нашел эту функцию в блоге

 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)))
    }`

как только вы загрузите функцию, вы можете просто

ggplotRegression(fit)

вы также можете пойти на ggplotregression( y ~ x + z + Q, data)

Надеюсь это поможет.

YellowEagle
источник
2

Если вы хотите соответствовать другим типам моделей, например кривой доза-реакция с использованием логистических моделей, вам также потребуется создать больше точек данных с функцией прогнозирования, если вы хотите иметь более плавную линию регрессии:

соответствие: ваше соответствие кривой логистической регрессии

#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
источник