## simulate some data - from mgcv::magic
set.seed(1)
n <- 400
x <- 0:(n-1)/(n-1)
f <- 0.2*x^11*(10*(1-x))^6+10*(10*x)^3*(1-x)^10
y <- f + rnorm(n, 0, sd = 2)
## load the splines package - comes with R
require(splines)
您使用bs()
公式中的函数为lm
正如你想要的 OLS 估计值。bs
提供由结、多项式次数等给出的基函数。
mod <- lm(y ~ bs(x, knots = seq(0.1, 0.9, by = 0.1)))
您可以将其视为线性模型。
> anova(mod)
Analysis of Variance Table
Response: y
Df Sum Sq Mean Sq F value Pr(>F)
bs(x, knots = seq(0.1, 0.9, by = 0.1)) 12 2997.5 249.792 65.477 < 2.2e-16 ***
Residuals 387 1476.4 3.815
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
关于结放置的一些提示。bs
有争论Boundary.knots
,默认情况下Boundary.knots = range(x)
- 因此当我指定knots
上面的论证中,我没有包括边界结。
Read ?bs
了解更多信息。
生成拟合样条曲线图
在评论中,我讨论了如何绘制拟合样条线。一种选择是根据协变量对数据进行排序。这适用于单个协变量,但不需要适用于 2 个或更多协变量。进一步的问题是,您只能在观测值处评估拟合样条线x
- 如果您对协变量进行了密集采样,那么这很好,但如果不是,则样条线可能看起来很奇怪,具有很长的线性部分。
更通用的解决方案是使用predict
从模型中生成一个或多个协变量新值的预测。在下面的代码中,我展示了如何对上面的模型执行此操作,预测 100 个均匀分布的值x
.
pdat <- data.frame(x = seq(min(x), max(x), length = 100))
## predict for new `x`
pdat <- transform(pdat, yhat = predict(mod, newdata = pdat))
## now plot
ylim <- range(pdat$y, y) ## not needed, but may be if plotting CIs too
plot(y ~ x)
lines(yhat ~ x, data = pdat, lwd = 2, col = "red")
这产生了