# [R] Piecewise Linear Regression

Achim Zeileis Achim.Zeileis at wu-wien.ac.at
Tue May 31 11:21:32 CEST 2005

```On Mon, 30 May 2005 19:38:58 -0400 (EDT) Abhyuday Mandal wrote:

> Hi,
>
> I need to fit a piecewise linear regression.
>
> x =
> c(6.25,6.25,12.50,12.50,18.75,25.00,25.00,25.00,31.25,31.25,37.50,37.
> 50,50.00,50.00,62.50,62.50,75.00,75.00,75.00,100.00,100.00) y =
> c(0.328,0.395,0.321,0.239,0.282,0.230,0.273,0.347,0.211,0.210,0.259,0
> .186,0.301,0.270,0.252,0.247,0.277,0.229,0.225,0.168,0.202)
>
> there are two change points. so the fitted curve should look like
>
>
>
> \
>  \  /\
>   \/  \
>        \
>         \
>
> How do I do this in R ?

There are various ways, as the previous replies already indicated. One
approach would be to consider this in a structural change framework, as
implemented in strucchange or segmented.

With strucchange you can do

## collect data
dat <- data.frame(y, x)
set.seed(123)
dat\$x <- dat\$x + rnorm(21, sd = 0.001)
## fit breakpoint model
bp <- breakpoints(y ~ x, data = dat)
## visualize
plot(x, y)
lines(x, fitted(bp))

The problem with breakpoints() is that it also fits models on very small
subsets, which can lead to singular regressor matrices if there are
bindings among the regressors. Hence, I did an ugly hack and added a
small error to avoid singularities.

segmented can also fit segmented regressions, but always fits broken
line segments (i.e. continuous curves) whereas strucchange fits fully
segmented models. The latter can also be easily fitted via
lm(y ~ fac/x)
if fac is a factor coding the different segments. See also ?breakfactor
in strucchange. So you can use any segmentation algorithm and then plug
the result easily into lm().
Z

> Thank you,
> Abhyuday
>
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help