在R中绘制多项式回归曲线

36

我有一个简单的多项式回归,方法如下:

attach(mtcars)
fit <- lm(mpg ~ hp + I(hp^2))

现在,我按照以下方式绘图

> plot(mpg~hp)
> points(hp, fitted(fit), col='red', pch=20)

这给我以下结果:

mpg与hp的图表

拟合值

我想将这些点连接成平滑曲线,使用直线会得到以下结果:

> lines(hp, fitted(fit), col='red', type='b')

折线图

我在这里错过了什么。我希望输出一个平滑的曲线连接这些点。


1
你真的不应该使用 attach,它可能会导致很多错误。 - Gregor Thomas
3个回答

36

我喜欢使用ggplot2,因为它通常非常直观,可以添加数据层。

library(ggplot2)
fit <- lm(mpg ~ hp + I(hp^2), data = mtcars)
prd <- data.frame(hp = seq(from = range(mtcars$hp)[1], to = range(mtcars$hp)[2], length.out = 100))
err <- predict(fit, newdata = prd, se.fit = TRUE)

prd$lci <- err$fit - 1.96 * err$se.fit
prd$fit <- err$fit
prd$uci <- err$fit + 1.96 * err$se.fit

ggplot(prd, aes(x = hp, y = fit)) +
  theme_bw() +
  geom_line() +
  geom_smooth(aes(ymin = lci, ymax = uci), stat = "identity") +
  geom_point(data = mtcars, aes(x = hp, y = mpg))

在此输入图片描述


当我使用您的代码(使用R 3.3.3和ggplot2_2.2.1 sp_1.2-4)时,我收到警告:忽略未知的美学元素:ymin,ymax。 - Pertinax
1
@TheThunderChimp 他们似乎在那里... http://ggplot2.tidyverse.org/reference/geom_smooth.html - Roman Luštrik
1
这显然是ggplot2最近版本的一个bug:https://github.com/tidyverse/ggplot2/issues/1939 - Pertinax

33

尝试:

lines(sort(hp), fitted(fit)[order(hp)], col='red', type='b') 

因为您数据集中的统计单位没有排序,所以当您使用lines时,它会变得混乱不堪。


除非您有均匀间隔的值或许多观测值,否则使用此“fitted()”方法将无法产生拟合多项式/函数的平滑实现。 - Gavin Simpson
@GavinSimpson 当然,生成一系列接近且间距均匀的点,并在其上拟合函数将产生更平滑的曲线。但我认为问题的目的是找到一种通过直线连接现有拟合点的方法,而不是曲线本身。 - Davide Passaretti

17

通常比较好的方法是使用 predict() 函数。选择一些 x 值,使用 predict() 生成对应的 y 值,并将它们绘制出来。可能会看起来像这样:

newdat = data.frame(hp = seq(min(mtcars$hp), max(mtcars$hp), length.out = 100))
newdat$pred = predict(fit, newdata = newdat)

plot(mpg ~ hp, data = mtcars)
with(newdat, lines(x = hp, y = pred))

输入图像描述

查看Roman的答案,以获取此方法的更高级版本,其中还计算了置信区间。在这两种情况下,实际的绘图解决方案是附带的-您可以使用基本图形、ggplot2或任何其他您喜欢的东西-关键是只需使用预测函数生成正确的y值。它是一种不错的方法,因为它适用于各种拟合,不仅仅是多项式线性模型。您可以将其与非线性模型、GLM、平滑样条等一起使用-任何具有predict方法的东西。


虽然没有明确解释,但Romain的回答已经展示了这种“predict()”方法,不是吗? - Gavin Simpson
4
是的,但正如你所说,它并没有被明确解释。这似乎是许多链接重复的标准信息来源 - 我认为提供一种一般方法的解释非常有价值,我还认为ggplot可能会成为新R用户的障碍,因此演示使用基础方法是不错的选择。但我会进行编辑以承认Roman的努力。 - Gregor Thomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接