在R中拟合两个断点的分段回归:一条水平线,一条直线,然后再一条水平线

时间:2019-03-09 10:25:45

标签: r regression breakpoints piecewise

我想对R中的两个断点进行分段回归:首先是一条斜率为0的水平线,然后是一条线性线,再是一条斜率为0的水平线。这两个断点也应拟合。

我的数据看起来像这样(总共我有60个类似的数据集):

x <- c(1.306, 1.566, 1.736, 1.854, 2.082, 2.328, 2.650, 2.886, 3.162, 3.392) 
y <- c(176.4, 188.0, 193.8, 179.4, 134.4, 119.0, 66.2, 58.2, 58.2, 41.2)

有人知道怎么做吗?

2 个答案:

答案 0 :(得分:1)

使用nls可以使x上的最小值和最大值符合以下条件。 ab是交点的x值,.lin1是中间部分的截距,.lin2是中间部分的斜率。

fm <- nls(y ~ cbind(1, pmax(pmin(x, b), a)), alg = "plinear", start = list(a = 2, b = 3))

给予:

Nonlinear regression model
  model: y ~ cbind(1, pmax(pmin(x, b), a))
   data: parent.frame()
       a        b    .lin1    .lin2 
   1.774    2.764  425.463 -134.940 
 residual sum-of-squares: 530.7

Number of iterations to convergence: 5 
Achieved convergence tolerance: 6.489e-09

水平部分处于与交点x值相对应的y值:

predict(fm, list(x = coef(fm)[1:2]))
## [1] 186.06667  52.53333

或可以计算为与最小和最大x值相对应的y值:

predict(fm, list(x = range(x)))
## [1] 186.06667  52.53333

我们可以像这样绘制点和拟合度:

plot(y ~ x)
xx <- seq(min(x), max(x), length = 100)
p <- predict(fm, list(x = xx))
lines(p ~ xx, col = "red")

screenshot

答案 1 :(得分:1)

更新后的答案要求更少的人机交互,不过, 基本上和以前一样。

您可以将这些点粗略地分为上下两部分 自动指向。一些过渡点可能 被分组为高点或低点,所以我们使用 boxplot.stats来消除任何看起来像 这些组中的异常值。然后,我们可以取平均值 高点和低点来估计水平高度 线。我们还使用非离群的上下点来 确定过渡的x值。

HighLine = (2*max(y) + min(y))/3
HighPoints = which(y >= boxplot.stats(y[y>HighLine])$stats[1])
HighY = mean(y[HighPoints])

LowLine = (max(y) + 2*min(y))/3
LowPoints = which(y <= boxplot.stats(y[y<LowLine])$stats[5])
LowY = mean(y[LowPoints])

x1 = max(x[HighPoints])
x2 = min(x[LowPoints])

plot(x,y)
lines(c(min(x), x1,x2, max(x)), c(HighY, HighY, LowY, LowY))

Piecewise Linear fit