The splines2 package (version 0.4.1) provides functions constructing a variety of regression spline bases that are not available from the splines package shipped with base R. Most functions have a very similar user interface with the function splines::bs(). To be more specific, it provides functions to construct basis matrix of
and their integrals (except C-spliness) and derivatives of given order by close-form recursive formulas. Compared to the splines package, splines2 allows piecewise constant basis for B-splines and provides a more user-friendly interface for their derivatives with consistent handling on NA’s. Most of the implementations had been (re)written in C++ with the help of Rcpp and RcppArmadillo since v0.3.0, which boosted the computational performance.
In the remaining of this vignette, we introduce the basic usage of most functions in the package through examples. The details of function syntax are available in the package manual and thus will not be discussed.
Function bSpline() provides B-spline basis matrix and allows degree = 0 for piece-wise constant bases, which extends the bs() function in package splines with a better computational performance. One example of linear B-splines with two internal knots is given as follows:
library(splines2)
knots <- c(0.3, 0.5, 0.6)
x <- seq(0, 1, 0.01)
bsMat <- bSpline(x, knots = knots, degree = 1, intercept = TRUE)
matplot(x, bsMat, type = "l", ylab = "y")
abline(v = knots, lty = 2, col = "gray")B-spline bases of degree one with two internal knots.
The close-form recursive formula of B-spline integrals and derivatives given by De Boor (1978) is implemented in function ibs() and dbs(), respectively. Two toy examples are given as follows:
ibsMat <- ibs(x, knots = knots, degree = 1, intercept = TRUE)
par(mfrow = c(1, 2))
matplot(x, bsMat, type = "l", ylab = "y")
abline(v = knots, h = 1, lty = 2, col = "gray")
matplot(x, ibsMat, type = "l", ylab = "y")
abline(v = knots, h = c(0.15, 0.2, 0.25), lty = 2, col = "gray")Piecewise linear B-spline bases (left) and their integrals (right).
bsMat <- bSpline(x, knots = knots, intercept = TRUE)
dbsMat <- dbs(x, knots = knots, intercept = TRUE)
par(mfrow = c(1, 2))
matplot(x, bsMat, type = "l", ylab = "y")
abline(v = knots, lty = 2, col = "gray")
matplot(x, dbsMat, type = "l", ylab = "y")
abline(v = knots, lty = 2, col = "gray")Cubic B-spline bases (left) and their first derivative (right).
We may also obtain the derivatives easily by the deriv() method as follows:
is_equivalent <- function(a, b) {
all.equal(a, b, check.attributes = FALSE)
}
stopifnot(is_equivalent(dbsMat, deriv(bsMat)))mSpline()M-splines (Ramsay 1988) can be considered as a normalized version of B-splines with unit integral within boundary knots. An example given by Ramsay (1988) was a quadratic M-splines with three internal knots placed at 0.3, 0.5, and 0.6. The boundary knots by default are the range of the data x, thus 0 and 1 in this example.
msMat <- mSpline(x, knots = knots, degree = 2, intercept = TRUE)
matplot(x, msMat, type = "l", ylab = "y")
abline(v = knots, lty = 2, col = "gray")Quadratic M-spline bases with three internal knots.
The derivative of given order of M-splines can be obtained by specifying a positive integer to argument dervis of mSpline(). Also, for an existing mSpline object generated by mSpline(), the deriv() method can be used conveniently. For example, the first derivative of the M-splines given in last example can be obtained equivalently as follows:
dmsMat1 <- mSpline(x, knots = knots, degree = 2, intercept = TRUE, derivs = 1)
dmsMat2 <- deriv(msMat)
stopifnot(is_equivalent(dmsMat1, dmsMat2))The function mSpline() produces periodic spline basis (based on M-splines) when periodic = TRUE is specified. The Boundary.knots defines the start and end points of the cyclic period.
x1 <- seq.int(0, 3, 0.01)
pmsMat <- mSpline(x1, knots = knots, degree = 3, intercept = TRUE,
periodic = TRUE, Boundary.knots = c(0, 1))
matplot(x1, pmsMat, type = "l", xlab = "x", ylab = "Periodic Bases")
abline(v = seq.int(0, 3), lty = 2, col = "gray")