Search code examples
rregressionbreakpointspiecewise

piecewise regression with two breakpoints to be fitted in R: a horizontal line, a straight line and then again a horizontal line


I want to do a piecewise regression with two breakpoint in R: first a horizontal line with slope 0, then a linear line and then again a horizontal line with slope 0. The two breakpoints should be fitted also.

My data looks like this (in total I have 60 similar datasets):

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)

Anybody knows how to do it?


Solution

  • Use nls to fit a line with a minimum and maximum on x like this. a and b are the x values of the intersection points and .lin1 is the intercept of the middle portion and .lin2 is the slope of the middle portion.

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

    giving:

    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
    

    The horizontal portions are at the y values corresponding to the x values of the intersection points:

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

    or can be computed as the y values corresponding to the smallest and largest x values:

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

    We can plot the points and the fit like this:

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

    screenshot