Title: | Regression Spline Functions and Classes |
---|---|
Description: | Regression spline functions and classes. |
Authors: | Douglas M. Bates <[email protected]> and William N. Venables <[email protected]> |
Maintainer: | R Core Team <[email protected]> |
License: | Part of R 4.4.1 |
Version: | 4.4.1 |
Built: | 2024-06-15 17:27:45 UTC |
Source: | base |
Regression spline functions and classes.
This package provides functions for working with regression
splines using the B-spline basis, bs
, and the
natural cubic spline basis, ns
.
For a complete list of functions, use library(help = "splines")
.
Douglas M. Bates [email protected] and William N. Venables [email protected]
Maintainer: R Core Team [email protected]
This is a generic function. Methods for this function coerce objects of given classes to vectors.
asVector(object)
asVector(object)
object |
An object. |
Methods for vector coercion in new classes must be created for the
asVector
generic instead of as.vector
. The
as.vector
function is internal and not easily extended.
Currently the only class with an asVector
method is the
xyVector
class.
a vector
Douglas Bates and Bill Venables
require(stats) ispl <- interpSpline( weight ~ height, women ) pred <- predict(ispl) class(pred) utils::str(pred) asVector(pred)
require(stats) ispl <- interpSpline( weight ~ height, women ) pred <- predict(ispl) class(pred) utils::str(pred) asVector(pred)
Create a monotone inverse of a monotone natural spline.
backSpline(object)
backSpline(object)
object |
an object that inherits from class |
An object of class polySpline
that contains the piecewise
polynomial representation of a function that has the appropriate
values and derivatives at the knot positions to be an inverse of the
spline represented by object
. Technically this object is not a
spline because the second derivative is not constrained to be
continuous at the knot positions. However, it is often a much better
approximation to the inverse than fitting an interpolation spline to
the y/x pairs.
Douglas Bates and Bill Venables
require(graphics) ispl <- interpSpline( women$height, women$weight ) bspl <- backSpline( ispl ) plot( bspl ) # plots over the range of the knots points( women$weight, women$height )
require(graphics) ispl <- interpSpline( women$height, women$weight ) bspl <- backSpline( ispl ) plot( bspl ) # plots over the range of the knots points( women$weight, women$height )
Generate the B-spline basis matrix for a polynomial spline.
bs(x, df = NULL, knots = NULL, degree = 3, intercept = FALSE, Boundary.knots = range(x), warn.outside = TRUE)
bs(x, df = NULL, knots = NULL, degree = 3, intercept = FALSE, Boundary.knots = range(x), warn.outside = TRUE)
x |
the predictor variable. Missing values are allowed. |
df |
degrees of freedom; one can specify |
knots |
the internal breakpoints that define the
spline. The default is |
degree |
degree of the piecewise polynomial—default is |
intercept |
if |
Boundary.knots |
boundary points at which to anchor the B-spline
basis (default the range of the non- |
warn.outside |
|
bs
is based on the function splineDesign
.
It generates a basis matrix for
representing the family of piecewise polynomials with the specified
interior knots and degree, evaluated at the values of x
. A
primary use is in modeling formulas to directly specify a piecewise
polynomial term in a model.
When Boundary.knots
are set inside range(x)
,
bs()
now uses a ‘pivot’ inside the respective boundary
knot which is important for derivative evaluation. In R versions
3.2.2, the boundary knot itself had been used as
pivot, which lead to somewhat wrong extrapolations.
A matrix of dimension c(length(x), df)
, where either df
was supplied or if knots
were supplied, df =
length(knots) + degree
plus one if there is an intercept. Attributes
are returned that correspond to the arguments to bs
, and
explicitly give the knots
, Boundary.knots
etc for use by
predict.bs()
.
Douglas Bates and Bill Venables. Tweaks by R Core, and a patch
fixing extrapolation “outside” Boundary.knots
by Trevor
Hastie.
Hastie, T. J. (1992) Generalized additive models. Chapter 7 of Statistical Models in S eds J. M. Chambers and T. J. Hastie, Wadsworth & Brooks/Cole.
ns
, poly
, smooth.spline
,
predict.bs
, SafePrediction
require(stats); require(graphics) bs(women$height, df = 5) summary(fm1 <- lm(weight ~ bs(height, df = 5), data = women)) ## example of safe prediction plot(women, xlab = "Height (in)", ylab = "Weight (lb)") ht <- seq(57, 73, length.out = 200) lines(ht, predict(fm1, data.frame(height = ht)))
require(stats); require(graphics) bs(women$height, df = 5) summary(fm1 <- lm(weight ~ bs(height, df = 5), data = women)) ## example of safe prediction plot(women, xlab = "Height (in)", ylab = "Weight (lb)") ht <- seq(57, 73, length.out = 200) lines(ht, predict(fm1, data.frame(height = ht)))
Create an interpolation spline, either from x
and y
vectors (default
method), or from a formula
/ data.frame
combination (formula
method).
interpSpline(obj1, obj2, bSpline = FALSE, period = NULL, ord = 4L, na.action = na.fail, sparse = FALSE)
interpSpline(obj1, obj2, bSpline = FALSE, period = NULL, ord = 4L, na.action = na.fail, sparse = FALSE)
obj1 |
either a numeric vector of |
obj2 |
if |
bSpline |
if |
period |
an optional positive numeric value giving a period for a periodic interpolation spline. |
ord |
an integer specifying the spline order, the number of
coefficients per interval. |
na.action |
a optional function which indicates what should happen
when the data contain |
sparse |
logical passed to the underlying
|
An object that inherits from (S3) class spline
. The object can be in
the B-spline representation, in which case it will be of class
nbSpline
for natural B-spline, or in the piecewise polynomial
representation, in which case it will be of class npolySpline
.
Douglas Bates and Bill Venables
splineKnots
,
splineOrder
,
periodicSpline
.
require(graphics); require(stats) ispl <- interpSpline( women$height, women$weight ) ispl2 <- interpSpline( weight ~ height, women ) # ispl and ispl2 should be the same plot( predict( ispl, seq( 55, 75, length.out = 51 ) ), type = "l" ) points( women$height, women$weight ) plot( ispl ) # plots over the range of the knots points( women$height, women$weight ) splineKnots( ispl )
require(graphics); require(stats) ispl <- interpSpline( women$height, women$weight ) ispl2 <- interpSpline( weight ~ height, women ) # ispl and ispl2 should be the same plot( predict( ispl, seq( 55, 75, length.out = 51 ) ), type = "l" ) points( women$height, women$weight ) plot( ispl ) # plots over the range of the knots points( women$height, women$weight ) splineKnots( ispl )
Generate the B-spline basis matrix for a natural cubic spline.
ns(x, df = NULL, knots = NULL, intercept = FALSE, Boundary.knots = range(x))
ns(x, df = NULL, knots = NULL, intercept = FALSE, Boundary.knots = range(x))
x |
the predictor variable. Missing values are allowed. |
df |
degrees of freedom. One can supply |
knots |
breakpoints that define the spline. The default is no
knots; together with the natural boundary conditions this results in
a basis for linear regression on |
intercept |
if |
Boundary.knots |
boundary points at which to impose the natural
boundary conditions and anchor the B-spline basis (default the range
of the data). If both |
ns
is based on the function splineDesign
. It
generates a basis matrix for representing the family of
piecewise-cubic splines with the specified sequence of
interior knots, and the natural boundary conditions. These enforce
the constraint that the function is linear beyond the boundary knots,
which can either be supplied or default to the extremes of the
data.
A primary use is in modeling formula to directly specify a natural spline term in a model: see the examples.
A matrix of dimension length(x) * df
where either df
was
supplied or if knots
were supplied,
df = length(knots) + 1 + intercept
.
Attributes are returned that correspond to the arguments to ns
,
and explicitly give the knots
, Boundary.knots
etc for
use by predict.ns()
.
Hastie, T. J. (1992) Generalized additive models. Chapter 7 of Statistical Models in S eds J. M. Chambers and T. J. Hastie, Wadsworth & Brooks/Cole.
bs
, predict.ns
, SafePrediction
require(stats); require(graphics) ns(women$height, df = 5) summary(fm1 <- lm(weight ~ ns(height, df = 5), data = women)) ## To see what knots were selected attr(terms(fm1), "predvars") ## example of safe prediction plot(women, xlab = "Height (in)", ylab = "Weight (lb)") ht <- seq(57, 73, length.out = 200) ; nD <- data.frame(height = ht) lines(ht, p1 <- predict(fm1, nD)) stopifnot(all.equal(p1, predict(update(fm1, . ~ splines::ns(height, df=5)), nD))) # not true in R < 3.5.0
require(stats); require(graphics) ns(women$height, df = 5) summary(fm1 <- lm(weight ~ ns(height, df = 5), data = women)) ## To see what knots were selected attr(terms(fm1), "predvars") ## example of safe prediction plot(women, xlab = "Height (in)", ylab = "Weight (lb)") ht <- seq(57, 73, length.out = 200) ; nD <- data.frame(height = ht) lines(ht, p1 <- predict(fm1, nD)) stopifnot(all.equal(p1, predict(update(fm1, . ~ splines::ns(height, df=5)), nD))) # not true in R < 3.5.0
Create a periodic interpolation spline, either from x
and
y
vectors, or from a formula/data.frame combination.
periodicSpline(obj1, obj2, knots, period = 2*pi, ord = 4L)
periodicSpline(obj1, obj2, knots, period = 2*pi, ord = 4L)
obj1 |
either a numeric vector of |
obj2 |
if |
knots |
optional numeric vector of knot positions. |
period |
positive numeric value giving the period for the
periodic spline. Defaults to |
ord |
integer giving the order of the spline, at least 2. Defaults
to 4. See |
An object that inherits from class spline
. The object can be in
the B-spline representation, in which case it will be a
pbSpline
object, or in the piecewise polynomial representation
(a ppolySpline
object).
Douglas Bates and Bill Venables
require(graphics); require(stats) xx <- seq( -pi, pi, length.out = 16 )[-1] yy <- sin( xx ) frm <- data.frame( xx, yy ) pispl <- periodicSpline( xx, yy, period = 2 * pi) pispl pispl2 <- periodicSpline( yy ~ xx, frm, period = 2 * pi ) stopifnot(all.equal(pispl, pispl2)) # pispl and pispl2 are the same plot( pispl ) # displays over one period points( yy ~ xx, col = "brown") plot( predict( pispl, seq(-3*pi, 3*pi, length.out = 101) ), type = "l" )
require(graphics); require(stats) xx <- seq( -pi, pi, length.out = 16 )[-1] yy <- sin( xx ) frm <- data.frame( xx, yy ) pispl <- periodicSpline( xx, yy, period = 2 * pi) pispl pispl2 <- periodicSpline( yy ~ xx, frm, period = 2 * pi ) stopifnot(all.equal(pispl, pispl2)) # pispl and pispl2 are the same plot( pispl ) # displays over one period points( yy ~ xx, col = "brown") plot( predict( pispl, seq(-3*pi, 3*pi, length.out = 101) ), type = "l" )
Create the piecewise polynomial representation of a spline object.
polySpline(object, ...) as.polySpline(object, ...)
polySpline(object, ...) as.polySpline(object, ...)
object |
An object that inherits from class |
... |
Optional additional arguments. At present no additional arguments are used. |
An object that inherits from class polySpline
. This is the
piecewise polynomial representation of a univariate spline function.
It is defined by a set of distinct numeric values called knots. The
spline function is a polynomial function between each successive pair
of knots. At each interior knot the polynomial segments on each side
are constrained to have the same value of the function and some of its
derivatives.
Douglas Bates and Bill Venables
interpSpline
,
periodicSpline
,
splineKnots
,
splineOrder
require(graphics) ispl <- polySpline(interpSpline( weight ~ height, women, bSpline = TRUE)) print( ispl ) # print the piecewise polynomial representation plot( ispl ) # plots over the range of the knots points( women$height, women$weight )
require(graphics) ispl <- polySpline(interpSpline( weight ~ height, women, bSpline = TRUE)) print( ispl ) # print the piecewise polynomial representation plot( ispl ) # plots over the range of the knots points( women$height, women$weight )
Evaluate a predefined spline basis at given values.
## S3 method for class 'bs' predict(object, newx, ...) ## S3 method for class 'ns' predict(object, newx, ...)
## S3 method for class 'bs' predict(object, newx, ...) ## S3 method for class 'ns' predict(object, newx, ...)
object |
the result of a call to |
newx |
the |
... |
Optional additional arguments. At present no additional arguments are used. |
An object just like object
, except evaluated at the new values
of x
.
These are methods for the generic function predict
for
objects inheriting from classes "bs"
or "ns"
. See
predict
for the general behavior of this function.
require(stats) basis <- ns(women$height, df = 5) newX <- seq(58, 72, length.out = 51) # evaluate the basis at the new data predict(basis, newX)
require(stats) basis <- ns(women$height, df = 5) newX <- seq(58, 72, length.out = 51) # evaluate the basis at the new data predict(basis, newX)
The predict
methods for the classes that inherit from the
virtual classes bSpline
and polySpline
are used to
evaluate the spline or its derivatives. The plot
method for a
spline object first evaluates predict
with the x
argument missing, then plots the resulting xyVector
with
type = "l"
.
## S3 method for class 'bSpline' predict(object, x, nseg = 50, deriv = 0, ...) ## S3 method for class 'nbSpline' predict(object, x, nseg = 50, deriv = 0, ...) ## S3 method for class 'pbSpline' predict(object, x, nseg = 50, deriv = 0, ...) ## S3 method for class 'npolySpline' predict(object, x, nseg = 50, deriv = 0, ...) ## S3 method for class 'ppolySpline' predict(object, x, nseg = 50, deriv = 0, ...)
## S3 method for class 'bSpline' predict(object, x, nseg = 50, deriv = 0, ...) ## S3 method for class 'nbSpline' predict(object, x, nseg = 50, deriv = 0, ...) ## S3 method for class 'pbSpline' predict(object, x, nseg = 50, deriv = 0, ...) ## S3 method for class 'npolySpline' predict(object, x, nseg = 50, deriv = 0, ...) ## S3 method for class 'ppolySpline' predict(object, x, nseg = 50, deriv = 0, ...)
object |
An object that inherits from the |
x |
A numeric vector of |
nseg |
A positive integer giving the number of segments in a set
of equally-spaced |
deriv |
An integer between 0 and |
... |
further arguments passed to or from other methods. |
an xyVector
with components
x |
the supplied or inferred numeric vector of |
y |
the value of the spline (or its |
Douglas Bates and Bill Venables
xyVector
,
interpSpline
,
periodicSpline
require(graphics); require(stats) ispl <- interpSpline( weight ~ height, women ) opar <- par(mfrow = c(2, 2), las = 1) plot(predict(ispl, nseg = 201), # plots over the range of the knots main = "Original data with interpolating spline", type = "l", xlab = "height", ylab = "weight") points(women$height, women$weight, col = 4) plot(predict(ispl, nseg = 201, deriv = 1), main = "First derivative of interpolating spline", type = "l", xlab = "height", ylab = "weight") plot(predict(ispl, nseg = 201, deriv = 2), main = "Second derivative of interpolating spline", type = "l", xlab = "height", ylab = "weight") plot(predict(ispl, nseg = 401, deriv = 3), main = "Third derivative of interpolating spline", type = "l", xlab = "height", ylab = "weight") par(opar)
require(graphics); require(stats) ispl <- interpSpline( weight ~ height, women ) opar <- par(mfrow = c(2, 2), las = 1) plot(predict(ispl, nseg = 201), # plots over the range of the knots main = "Original data with interpolating spline", type = "l", xlab = "height", ylab = "weight") points(women$height, women$weight, col = 4) plot(predict(ispl, nseg = 201, deriv = 1), main = "First derivative of interpolating spline", type = "l", xlab = "height", ylab = "weight") plot(predict(ispl, nseg = 201, deriv = 2), main = "Second derivative of interpolating spline", type = "l", xlab = "height", ylab = "weight") plot(predict(ispl, nseg = 401, deriv = 3), main = "Third derivative of interpolating spline", type = "l", xlab = "height", ylab = "weight") par(opar)
Evaluate the design matrix for the B-splines defined by knots
at the values in x
.
splineDesign(knots, x, ord = 4, derivs, outer.ok = FALSE, sparse = FALSE) spline.des (knots, x, ord = 4, derivs, outer.ok = FALSE, sparse = FALSE)
splineDesign(knots, x, ord = 4, derivs, outer.ok = FALSE, sparse = FALSE) spline.des (knots, x, ord = 4, derivs, outer.ok = FALSE, sparse = FALSE)
knots |
a numeric vector of knot positions (which will be sorted increasingly if needed). |
x |
a numeric vector of values at which to evaluate the B-spline
functions or derivatives. Unless |
ord |
a positive integer giving the order of the spline function. This is the number of coefficients in each piecewise polynomial segment, thus a cubic spline has order 4. Defaults to 4. |
derivs |
an integer vector with values between |
outer.ok |
logical indicating if |
sparse |
logical indicating if the result should inherit from class
|
A matrix with length(x)
rows and length(knots) - ord
columns. The i-th row of the matrix contains the coefficients of the
B-splines (or the indicated derivative of the B-splines) defined by
the knot
vector and evaluated at the i-th value of x
.
Each B-spline is defined by a set of ord
successive knots so
the total number of B-splines is length(knots) - ord
.
The older spline.des
function takes the same arguments but
returns a list with several components including knots
,
ord
, derivs
, and design
. The design
component is the same as the value of the splineDesign
function.
Douglas Bates and Bill Venables
require(graphics) splineDesign(knots = 1:10, x = 4:7) splineDesign(knots = 1:10, x = 4:7, derivs = 1) ## visualize band structure Matrix::drop0(zapsmall(6*splineDesign(knots = 1:40, x = 4:37, sparse = TRUE))) knots <- c(1,1.8,3:5,6.5,7,8.1,9.2,10) # 10 => 10-4 = 6 Basis splines x <- seq(min(knots)-1, max(knots)+1, length.out = 501) bb <- splineDesign(knots, x = x, outer.ok = TRUE) plot(range(x), c(0,1), type = "n", xlab = "x", ylab = "", main = "B-splines - sum to 1 inside inner knots") mtext(expression(B[j](x) *" and "* sum(B[j](x), j == 1, 6)), adj = 0) abline(v = knots, lty = 3, col = "light gray") abline(v = knots[c(4,length(knots)-3)], lty = 3, col = "gray10") lines(x, rowSums(bb), col = "gray", lwd = 2) matlines(x, bb, ylim = c(0,1), lty = 1)
require(graphics) splineDesign(knots = 1:10, x = 4:7) splineDesign(knots = 1:10, x = 4:7, derivs = 1) ## visualize band structure Matrix::drop0(zapsmall(6*splineDesign(knots = 1:40, x = 4:37, sparse = TRUE))) knots <- c(1,1.8,3:5,6.5,7,8.1,9.2,10) # 10 => 10-4 = 6 Basis splines x <- seq(min(knots)-1, max(knots)+1, length.out = 501) bb <- splineDesign(knots, x = x, outer.ok = TRUE) plot(range(x), c(0,1), type = "n", xlab = "x", ylab = "", main = "B-splines - sum to 1 inside inner knots") mtext(expression(B[j](x) *" and "* sum(B[j](x), j == 1, 6)), adj = 0) abline(v = knots, lty = 3, col = "light gray") abline(v = knots[c(4,length(knots)-3)], lty = 3, col = "gray10") lines(x, rowSums(bb), col = "gray", lwd = 2) matlines(x, bb, ylim = c(0,1), lty = 1)
Return the knot vector corresponding to a spline object.
splineKnots(object)
splineKnots(object)
object |
an object that inherits from class |
A non-decreasing numeric vector of knot positions.
Douglas Bates and Bill Venables
ispl <- interpSpline( weight ~ height, women ) splineKnots( ispl )
ispl <- interpSpline( weight ~ height, women ) splineKnots( ispl )
Return the order of a spline object.
splineOrder(object)
splineOrder(object)
object |
An object that inherits from class |
The order of a spline is the number of coefficients in each piece of the piecewise polynomial representation. Thus a cubic spline has order 4.
A positive integer.
Douglas Bates and Bill Venables
splineKnots
,
interpSpline
,
periodicSpline
splineOrder( interpSpline( weight ~ height, women ) )
splineOrder( interpSpline( weight ~ height, women ) )
xyVector
ObjectCreate an object to represent a set of x-y pairs. The resulting
object can be treated as a matrix or as a data frame or as a vector.
When treated as a vector it reduces to the y
component only.
The result of functions such as predict.spline
is returned as
an xyVector
object so the x-values used to generate the
y-positions are retained, say for purposes of generating plots.
xyVector(x, y)
xyVector(x, y)
x |
a numeric vector |
y |
a numeric vector of the same length as |
An object of class xyVector
with components
x |
a numeric vector |
y |
a numeric vector of the same length as |
Douglas Bates and Bill Venables
require(stats); require(graphics) ispl <- interpSpline( weight ~ height, women ) weights <- predict( ispl, seq( 55, 75, length.out = 51 )) class( weights ) plot( weights, type = "l", xlab = "height", ylab = "weight" ) points( women$height, women$weight ) weights
require(stats); require(graphics) ispl <- interpSpline( weight ~ height, women ) weights <- predict( ispl, seq( 55, 75, length.out = 51 )) class( weights ) plot( weights, type = "l", xlab = "height", ylab = "weight" ) points( women$height, women$weight ) weights