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

在R中拟合两个断点的分段回归:一条水平线,一条直线,然后是一条水平线,r,regression,breakpoints,piecewise,R,Regression,Breakpoints,Piecewise,我想用R中的两个断点进行分段回归:首先是斜率为0的水平线,然后是线性线,然后是斜率为0的水平线。还应安装两个断点 我的数据如下(总共有60个类似的数据集): x使用nls在x上以最小值和最大值拟合一行,如下所示a和b是交点的x值,。lin1是中间部分的截距,。lin2是中间部分的坡度 fm <- nls(y ~ cbind(1, pmax(pmin(x, b), a)), alg = "plinear", start = list(a = 2, b = 3)) 水平部分位于与交点的x值相

我想用R中的两个断点进行分段回归:首先是斜率为0的水平线,然后是线性线,然后是斜率为0的水平线。还应安装两个断点

我的数据如下(总共有60个类似的数据集):


x使用
nls
x
上以最小值和最大值拟合一行,如下所示
a
b
是交点的x值,
。lin1
是中间部分的截距,
。lin2
是中间部分的坡度

fm <- nls(y ~ cbind(1, pmax(pmin(x, b), a)), alg = "plinear", start = list(a = 2, b = 3))
水平部分位于与交点的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")
绘图(y~x)

xx更新了答案,减少了人与人之间的互动, 答案和以前基本相同

您可以将点粗略地分组为上部和下部 自动点数。一些过渡点可能会 使用上下点进行分组,所以我们使用
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))
HighLine=(2*最大值(y)+最小值(y))/3
高点=哪个(y>=boxplot.stats(y[y>高点])$stats[1])
HighY=平均值(y[高点])
下限=(最大值(y)+2*最小值(y))/3

LowPoints=哪个(y)(如果可能有用的话,我发现偏移量为“a*exp(-0.5*pow((x-b)/c,2.0))+offset”的高斯峰值方程,参数a=1.455460522554448E+02,b=1.5839534147665826E+00,c=-5.689903006429440E-01,偏移量=4.6871995528236809E+01给出了一个合适的拟合,得到了R平方=0.9865和RMSE=6.742这真的是一个很大的帮助,谢谢!唯一的问题是我有60个这样的数据集,x的范围不同。所以对于一些初始值例如,另一个数据集是:x我尝试了这些作为起始值:a0=min(x,na.rm=FALSE)+0.3;b0=max(x,na.rm=FALSE)-0.3如果您已经删除了na,另一种可能是
start=list(a=mean(head(x,k)),b=mean(tail(x,k)))
其中适当地选择了
k
。您的起始值对应于k=1。如果您的某些数据实际上不遵循此模型,则您可能无法收敛这些集合,因此期望完全自动的结果可能不现实。
plot(y ~ x)
xx <- seq(min(x), max(x), length = 100)
p <- predict(fm, list(x = xx))
lines(p ~ xx, col = "red")
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))