Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Export fitted regression splines (constructed by 'bs' or 'ns') as piecewise polynomials

Take for instance the following one-knot, degree two, spline:

library(splines)
library(ISLR)
fit.spline <- lm(wage~bs(age, knots=c(42), degree=2), data=Wage)
summary(fit.spline)

I see estimates that I don't expect.

Coefficients:
                                  Estimate  Std. Error   t value    Pr(>|t|)   
(Intercept)                           57.349   3.950   14.518   < 2e-16 ***
bs(age, knots = c(42), degree = 2)1   59.511   5.786   10.285   < 2e-16 ***
bs(age, knots = c(42), degree = 2)2   65.722   4.076   16.122   < 2e-16 ***
bs(age, knots = c(42), degree = 2)3   37.170   9.722    3.823  0.000134 ***

Is there a way to extract the quadratic model (and its coefficients) for before and after the knot? That is, how can I extract the two quadratic models before and after the cut point of age = 42?

Using summary(fit.spline) yields coefficients, but (to my understanding) they are not meaningful for interpretation.

like image 842
shide Avatar asked Jun 24 '17 17:06

shide


People also ask

What is piecewise spline?

In mathematics, a spline is a special function defined piecewise by polynomials. In interpolating problems, spline interpolation is often preferred to polynomial interpolation because it yields similar results, even when using low degree polynomials, while avoiding Runge's phenomenon for higher degrees.

What is spline regression model?

Spline regression modeling looks for points in the data that would indicate where changes occur. These. points are referred to as “knots.” Spline regression models provide a means of capturing these changes smoothly. and joining the segments without the usual “break” between the segments.

What are splines in stata?

Linear splines allow estimating the relationship between y and x as a piecewise linear function, which is a function composed of linear segments—straight lines.

What is cubic spline regression?

Cubic regression spline is a form of generalized linear models in regression analysis. Also known as B-spline, it is supported by a series of interior basis functions on the interval with chosen knots. Cubic regression splines are widely used on modeling nonlinear data and interaction between variables.


1 Answers

I was constantly asked to wrap up the idea in my original answer into a user-friendly function, able to reparametrize a fitted linear or generalized linear model with a bs or ns term. Eventually I rolled out a small R package SplinesUtils at https://github.com/ZheyuanLi/SplinesUtils (with a PDF version package manual). You can install it via

## make sure you have the `devtools` package avaiable
devtools::install_github("ZheyuanLi/SplinesUtils")

The function to be used here is RegBsplineAsPiecePoly.

library(SplinesUtils)

library(splines)
library(ISLR)
fit.spline <- lm(wage ~ bs(age, knots=c(42), degree=2), data = Wage)

ans1 <- RegBsplineAsPiecePoly(fit.spline, "bs(age, knots = c(42), degree = 2)")
ans1
#2 piecewise polynomials of degree 2 are constructed!
#Use 'summary' to export all of them.
#The first 2 are printed below.
#8.2e-15 + 4.96 * (x - 18) + 0.0991 * (x - 18) ^ 2
#61.9 + 0.2 * (x - 42) + 0.0224 * (x - 42) ^ 2

## coefficients as a matrix
ans1$PiecePoly$coef
#              [,1]        [,2]
#[1,]  8.204641e-15 61.91542748
#[2,]  4.959286e+00  0.20033307
#[3,] -9.914485e-02 -0.02240887

## knots
ans1$knots
#[1] 18 42 80

The function defaults to parametrize piecewise polynomials in shifted form (see ?PiecePoly). You can set shift = FALSE for a non-shifted version.

ans2 <- RegBsplineAsPiecePoly(fit.spline, "bs(age, knots = c(42), degree = 2)",
                              shift = FALSE)
ans2
#2 piecewise polynomials of degree 2 are constructed!
#Use 'summary' to export all of them.
#The first 2 are printed below.
#-121 + 8.53 * x + 0.0991 * x ^ 2
#14 + 2.08 * x + 0.0224 * x ^ 2

## coefficients as a matrix
ans2$PiecePoly$coef
#              [,1]        [,2]
#[1,] -121.39007747 13.97219046
#[2,]    8.52850050  2.08267822
#[3,]   -0.09914485 -0.02240887

You can predict the splines with predict.

xg <- 18:80
yg1 <- predict(ans1, xg)  ## use shifted form
yg2 <- predict(ans2, xg)  ## use non-shifted form
all.equal(yg1, yg2)
#[1] TRUE

But since there is an intercept in the model, the predicted values would differ from model prediction by the intercept.

yh <- predict(fit.spline, data.frame(age = xg))
intercept <- coef(fit.spline)[[1]]
all.equal(yh, yg1 + intercept, check.attributes = FALSE)
#[1] TRUE

The package has summary, print, plot, predict and solve methods for a "PiecePoly" class. Explore the package for more.

like image 186
Zheyuan Li Avatar answered Sep 28 '22 15:09

Zheyuan Li