Додавання регресійної лінії на ggplot


120

Я дуже намагаюся додати лінію регресії на ggplot. Я спершу спробував з abline, але мені не вдалося змусити його працювати. Потім я спробував це ...

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)

Але це теж не працює.

Відповіді:


170

В цілому, щоб забезпечити свою власну формулу , яку ви повинні використовувати аргументи 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')

46

Як я щойно зрозумів, якщо у вас є модель, встановлена ​​на декількох лінійних регресіях , вищезгадане рішення не буде працювати.

Ви повинні створити лінію вручну у вигляді фрейму даних, який містить передбачувані значення для початкового фрейму даних (у вашому випадку 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))

Кілька ЛР

# 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


1
Одне, на що слід стежити, - це умовність lm (y ~ x). Я трохи розвернувся для другого читання, оскільки змінна, яку ви "прогнозуєте", знаходиться на осі x. Хоча чудова відповідь.
колорит

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для збільшення масштаб .


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)

Сподіваюся, це допомагає.


2

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

fit: відповідність кривої логістичної регресії

#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)))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.