【问题标题】:Adding a regression line on a ggplot在 ggplot 上添加回归线
【发布时间】:2013-03-16 01:12:29
【问题描述】:

我正在努力在 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)

但它也不起作用。

【问题讨论】:

标签: r ggplot2 regression linear-regression


【解决方案1】:

一般来说,要提供您自己的公式,您应该使用参数 xy,它们将对应于您在 ggplot() 中提供的值 - 在这种情况下,x 将被解释为 x.plot 和 @987654326 @ 为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)

如果您使用在 ggplot() 调用中提供的相同 x 和 y 值并且需要绘制线性回归线,那么您不需要使用 geom_smooth() 中的公式,只需提供 @987654333 @。

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

【讨论】:

    【解决方案2】:

    正如我刚刚想到的,如果您有一个适合多元线性回归的模型,上述解决方案将不起作用。

    您必须手动将您的行创建为包含原始数据框的预测值的数据框(在您的情况下为 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)
    

    【讨论】:

    • 需要注意的一点是约定是 lm(y~x)。由于您“预测”的变量位于 x 轴上,因此我稍微转身看了一遍。不过答案很好。
    【解决方案3】:

    简单而通用的解决方案是使用slopeinterceptgeom_abline 画一条线。散点图和lm 对象的用法示例:

    library(tidyverse)
    petal.lm <- lm(Petal.Length ~ Petal.Width, iris)
    
    ggplot(iris, aes(x = Petal.Width, y = Petal.Length)) + 
      geom_point() + 
      geom_abline(slope = coef(petal.lm)[["Petal.Width"]], 
                  intercept = coef(petal.lm)[["(Intercept)"]])
    

    coef 用于提取提供给lm 的公式的系数。如果您有其他线性模型对象或线要绘制,只需插入斜率和截距值。

    【讨论】:

    • 因此您无需担心公式的排序或只需添加+0 即可使用名称。 data.lm$coefficients[['(Intercept)']]data.lm$coefficients[['DepDelay']].
    • (几乎)总是(Intercept) 会排在第一位。这些名称确实使代码更清晰。
    • 我认为这是最好的答案——它是最通用的。
    • 我如何利用它(绘制它)?
    • @Ben 抱歉回复晚了。由于这个答案引起了一些关注,因此我添加了 MWE 的详细信息。
    【解决方案4】:

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

    一旦你加载了函数,你就可以简单地

    ggplotRegression(fit)
    

    你也可以去ggplotregression( y ~ x + z + Q, data)

    希望这会有所帮助。

    【讨论】:

    • 对此代码的解释将大大改善这个答案。标签是不必要的,您应该使用coef(fit) 而不是直接访问系数*.com/questions/17824461/…
    【解决方案5】:

    如果您想拟合其他类型的模型,例如使用逻辑模型的剂量反应曲线,您还需要使用 predict 函数创建更多数据点,如果您想获得更平滑的回归线:

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

    【讨论】: