2012-04-27 174 views
1

我使用样条曲线包的bs函数为图形目的创建b样条平滑曲线。 (至少有一个报告表明,Excel使用三阶b样条作为其平滑线条图,我希望能够复制这些曲线。)我无法理解bs函数所需的参数。代表代码遵循下面,作为适于从BS文档:指定在样条曲线中使用bs函数的b样条拟合的自由度程序包

require(splines) 
require(ggplot2) 
n <- 10 
x <- 1:10 
y <- rnorm(n) 
d <- data.frame(x=x, y=y) 
summary(fm1 <- lm(y ~ bs(x, degree=3)), data=d) 
x.spline <- seq(1, 10, length.out=n*10) 
spline.data <- data.frame(x=x.spline, y=predict(fm1, data.frame(x=x.spline))) 
ggplot(d, aes(x,y)) + geom_point + geom_line(aes(x,y), data=spline.data) 

在BS文档中的示例代码指定DF = 5在调用BS,并且不指定程度。我不知道我有多少自由度。我所知道的是我想要一个三阶b样条。我已经尝试过指定df的不同值,或者除了度数之外,我得到的结果大不相同。这就是为什么我怀疑df的规格是这里的问题。在这种情况下我将如何计算df?

帮助文件建议df =长度(节)+度。如果我将内部点视为结点,则此示例给出了df = 11,这将生成错误消息和无意义的样条拟合。

预先感谢您。

我显然不清楚我的意图。我试图做到这一点: How can I use spline() with ggplot?,但与b样条。

回答

2

你不应该试图去适应每一点。目标是找到一个可接受的摘要,但取决于有限数量的结。将多项式的hte度提高到缺省值3以上没有太大的价值。只有10分,你肯定不希望df = 11。尝试df = 5,结果应该相当平坦。 rms/Hnisc软件包作者Frank Harrell更喜欢受限三次样条,因为在极端情况下的预测是线性的,因此与其他多项式基数相比,预测更少。

我纠正了几个拼写错误,并增加了一个knots参数,使您的工作代码:

require(splines) 
require(ggplot2); set.seed(trunc(100000*pi)) 

n <- 10 
x <- 1:10 
y <- rnorm(n) 
d <- data.frame(x=x, y=y) 
summary(fm1 <- lm(y ~ bs(x, degree=3, knots=2)), data=d) 
x.spline <- seq(1, 10, length.out=n*10) 
spline.data <- data.frame(x=x.spline, y=predict(fm1, data.frame(x=x.spline))) 
ggplot(d, aes(x,y)) + geom_point() + geom_line(aes(x,y), data=spline.data) 

我来到距变化与意见randomseed弗兰克·哈勒尔知道他在谈论的锻炼。在使用包裹时,我不会在极端情况下得到同样的行为。

+0

您能否提供Frank Harrel评论的来源? – takje 2017-09-03 13:35:41

+0

我看的第一个地方是他的RMS书的索引。我记得他有一个专门研究受限立方样条的部分。 – 2017-09-03 17:48:50

0

我做了一些工作,并提出以下建议。首先,道歉。我所寻找的是一个平滑样条,而不是一个回归样条。我没有足够的词汇来正确地描述问题。尽管bs()的帮助文件中的示例似乎提供了此示例,但函数不会为我的示例数据提供相同的行为。在stats包中还有另一个函数smooth.spline,它提供了我所需要的。

set.seed(tunc(100000*pi)) 
n <- 10 
x <- 1:n 
xx <- seq(1, n, length.out=200) 
y <- rnorm(n) 
d <- data.frame(x=x, y=y) 
spl <- smooth.spline(x,y, spar=0.1) 
spline.data <- data.frame(y=predict(spl,xx)) 
ggplot(d,aes(x,y)) + geom_point() + geom_line(aes(x,y), spline.data) 
spl2 <- smooth.spline(x, y, control= 
      list(trace=TRUE, tol=1e-6, spar=0.1, low=-1.5, high=0.3)) 
spline.data2 <- data.frame(predit(spl2,xx)) 
ggplot(d,aes(x,y)) + geom_point() + geom_line(aes(x,y), spline.data2) 

这两个调用smooth.spline表示两种方法。第一个手动指定平滑参数,第二个迭代到最佳解决方案。我发现我必须正确地限制优化以获得我之后的解决方案类型。

结果旨在匹配Excel线图所使用的b样条。我有合作者认为Excel图形是标准的,我需要至少与该性能相匹配。