I have two ideas, both with flaws. Perhaps you can customize one of them to suit your needs. Unfortunately, access to the Drive is currently not possible, so some artificial data is used.
1. Manually fit polynomial models
Here you can specify which models you like, some segments may be lm, some polynomials, etc.
the code:
library(segmented) library(ggplot2) library(data.table) # Data set.seed(12) xx <- 1:100 yy <- 2 + 1.5 * pmax(xx-35, 0) - 1.5 * pmax(xx-70, 0) + 15 * pmax(runif(100) - 0.5, 0) + rnorm(100, 0, 2) dt <- data.table(x = xx, y = yy, type = 'act') dt_all <- copy(dt) # lm lm_lin <- lm(y ~ x, data = dt) summary(lm_lin) # Find segments lm_seg <- segmented( lm_lin, seg.Z = ~ x, psi = list(x = c(30, 80))) # "Manual" lm's breaks <- unname(lm_seg$psi[, 'Est.']) lm_poly1 <- lm(y ~ poly(x, 4), data = dt[x < breaks[1], ]) lm_2 <- lm(y ~ x, data = dt[x > breaks[1] & x < breaks[2], ]) lm_poly3 <- lm(y ~ poly(x, 4), data = dt[x > breaks[2], ]) dt_all <- rbind( dt_all, data.table(x = xx, y = c( predict(lm_poly1), predict(lm_2), predict(lm_poly3)), type = 'lm_poly' ) )
2. Install the model using breaks from segmented
and some splines
Here you get a smooth transition between segments, but you have much less control over what is happening.
# Using splines for smooth segments library(mgcv) spl <- gam(y ~ s(x, bs = "cc", k = 12), data = dt, knots = list(xx = breaks))
Both can be done using, for example, list()
and lapply()
to automate bits (for a different number of breaks, etc.).
Edit:
By changing the arguments poly
and s
, you can get some βbetterβ fit models, but for the gam
errors at the edges are pretty big, see degree = 6
and k = 30
: