splines2/ 0000755 0001762 0000144 00000000000 14121634402 012006 5 ustar ligges users splines2/NAMESPACE 0000644 0001762 0000144 00000002606 14121502500 013222 0 ustar ligges users # Generated by roxygen2: do not edit by hand
S3method(deriv,bSpline2)
S3method(deriv,bernsteinPoly)
S3method(deriv,cSpline)
S3method(deriv,dbs)
S3method(deriv,iSpline)
S3method(deriv,ibs)
S3method(deriv,mSpline)
S3method(deriv,naturalSpline)
S3method(knots,bSpline2)
S3method(knots,bernsteinPoly)
S3method(knots,cSpline)
S3method(knots,dbs)
S3method(knots,iSpline)
S3method(knots,ibs)
S3method(knots,mSpline)
S3method(knots,naturalSpline)
S3method(makepredictcall,bSpline2)
S3method(makepredictcall,bernsteinPoly)
S3method(makepredictcall,cSpline)
S3method(makepredictcall,dbs)
S3method(makepredictcall,iSpline)
S3method(makepredictcall,ibs)
S3method(makepredictcall,mSpline)
S3method(makepredictcall,naturalSpline)
S3method(predict,bSpline2)
S3method(predict,bernsteinPoly)
S3method(predict,cSpline)
S3method(predict,dbs)
S3method(predict,iSpline)
S3method(predict,ibs)
S3method(predict,mSpline)
S3method(predict,naturalSpline)
S3method(print,bSpline2)
S3method(print,bernsteinPoly)
S3method(print,cSpline)
S3method(print,dbs)
S3method(print,iSpline)
S3method(print,ibs)
S3method(print,mSpline)
S3method(print,naturalSpline)
export(bSpline)
export(bernsteinPoly)
export(cSpline)
export(dbs)
export(iSpline)
export(ibs)
export(mSpline)
export(naturalSpline)
importFrom(Rcpp,sourceCpp)
importFrom(stats,deriv)
importFrom(stats,knots)
importFrom(stats,makepredictcall)
importFrom(stats,predict)
useDynLib(splines2)
splines2/README.md 0000644 0001762 0000144 00000023654 14115272534 013306 0 ustar ligges users splines2
================
[](https://CRAN.R-project.org/package=splines2)
[](https://CRAN.R-project.org/package=splines2)
[](https://CRAN.R-project.org/package=splines2)
[](https://github.com/wenjie2wang/splines2/actions)
[](https://codecov.io/gh/wenjie2wang/splines2)
[](https://doi.org/10.6339/21-JDS1020)
The R package **splines2** is intended to be a user-friendly
*supplement* to the base package **splines**.
## Features
The package **splines2** (version 0.4.5.9000) provides functions to
construct basis matrices of
- B-splines
- M-splines
- I-splines
- convex splines (C-splines)
- periodic M-splines
- natural cubic splines
- generalized Bernstein polynomials
- their integrals (except C-splines) and derivatives of given order by
closed-form recursive formulas
In addition to the R interface, **splines2** provides a C++ header-only
library integrated with **Rcpp**, which allows the construction of
spline basis functions directly in C++ with the help of **Rcpp** and
**RcppArmadillo**. Thus, it can also be treated as one of the **Rcpp\***
packages. A toy example package that uses the C++ interface is available
[here](https://github.com/wenjie2wang/example-pkg-Rcpp-splines2).
## Installation of CRAN Version
You can install the released version from
[CRAN](https://CRAN.R-project.org/package=splines2).
``` r
install.packages("splines2")
```
## Development
The latest version of the package is under development at
[GitHub](https://github.com/wenjie2wang/splines2). If it is able to pass
the automated package checks, one may install it by
``` r
if (! require(remotes)) install.packages("remotes")
remotes::install_github("wenjie2wang/splines2", upgrade = "never")
```
## Getting Started
The [Online document](https://wwenjie.org/splines2) provides a reference
for all functions and contains the following vignettes:
- [Demonstration of the common usages in R through
examples](https://wwenjie.org/splines2/articles/splines2-intro).
- [Introduction to the usage with
Rcpp](https://wwenjie.org/splines2/articles/splines2-wi-rcpp)
## Performance
Since v0.3.0, the implementation of the main functions has been
rewritten in C++ with the help of the **Rcpp** and **RcppArmadillo**
packages. The computational performance has thus been boosted and
comparable with the function `splines::splineDesign()`.
Some quick micro-benchmarks are provided for reference as follows:
``` r
library(microbenchmark)
library(splines)
library(splines2)
set.seed(123)
x <- runif(1e3)
degree <- 3
ord <- degree + 1
internal_knots <- seq.int(0.1, 0.9, 0.1)
boundary_knots <- c(0, 1)
all_knots <- sort(c(internal_knots, rep(boundary_knots, ord)))
## check equivalency of outputs
my_check <- function(values) {
all(sapply(values[- 1], function(x) {
all.equal(unclass(values[[1]]), x, check.attributes = FALSE)
}))
}
```
For B-splines, function `splines2::bSpline()` provides equivalent
results with `splines::bs()` and `splines::splineDesign()`, and is about
3x faster than `bs()` and 2x faster than `splineDesign()` for this
example.
``` r
## B-splines
microbenchmark(
"splines::bs" = bs(x, knots = internal_knots, degree = degree,
intercept = TRUE, Boundary.knots = boundary_knots),
"splines::splineDesign" = splineDesign(x, knots = all_knots, ord = ord),
"splines2::bSpline" = bSpline(
x, knots = internal_knots, degree = degree,
intercept = TRUE, Boundary.knots = boundary_knots
),
check = my_check,
times = 1e3,
unit = "relative"
)
```
Unit: relative
expr min lq mean median uq max neval cld
splines::bs 3.6523 3.5555 3.5506 3.4736 3.5177 1.1974 1000 c
splines::splineDesign 2.2324 2.1404 2.1467 2.0619 2.0942 1.0849 1000 b
splines2::bSpline 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1000 a
Similarly, for derivatives of B-splines, `splines2::dbs()` provides
equivalent results with `splines::splineDesign()`, and is about 2x
faster.
``` r
## Derivatives of B-splines
derivs <- 2
microbenchmark(
"splines::splineDesign" = splineDesign(x, knots = all_knots,
ord = ord, derivs = derivs),
"splines2::dbs" = dbs(x, derivs = derivs, knots = internal_knots,
degree = degree, intercept = TRUE,
Boundary.knots = boundary_knots),
check = my_check,
times = 1e3,
unit = "relative"
)
```
Unit: relative
expr min lq mean median uq max neval cld
splines::splineDesign 2.678 2.519 2.4873 2.4508 2.5028 1.0712 1000 b
splines2::dbs 1.000 1.000 1.0000 1.0000 1.0000 1.0000 1000 a
The **splines** package does not contain an implementation for integrals
of B-splines. Thus, we performed a comparison with package **ibs**
(version `r packageVersion("ibs")`), where the function `ibs::ibs()` was
also implemented in **Rcpp**.
``` r
## integrals of B-splines
set.seed(123)
coef_sp <- rnorm(length(all_knots) - ord)
microbenchmark(
"ibs::ibs" = ibs::ibs(x, knots = all_knots, ord = ord, coef = coef_sp),
"splines2::ibs" = as.numeric(
splines2::ibs(x, knots = internal_knots, degree = degree,
intercept = TRUE, Boundary.knots = boundary_knots) %*%
coef_sp
),
check = my_check,
times = 1e3,
unit = "relative"
)
```
Unit: relative
expr min lq mean median uq max neval cld
ibs::ibs 9.3175 8.4242 9.3377 9.6631 9.6052 30.53 1000 b
splines2::ibs 1.0000 1.0000 1.0000 1.0000 1.0000 1.00 1000 a
The function `ibs::ibs()` returns the integrated B-splines instead of
the integrals of spline basis functions. Thus, we applied the same
coefficients to the basis functions from `splines2::ibs()` for
equivalent results, which was still much faster than `ibs::ibs()`.
For natural cubic splines (based on B-splines), `splines::ns()` uses the
QR decomposition to find the null space of the second derivatives of
B-spline basis functions at boundary knots, while
`splines2::naturalSpline()` utilizes the closed-form null space derived
from the second derivatives of cubic B-splines, which produces
nonnegative basis functions (within boundary) and is more
computationally efficient.
``` r
microbenchmark(
"splines::ns" = ns(x, knots = internal_knots, intercept = TRUE,
Boundary.knots = boundary_knots),
"splines2::naturalSpline" = naturalSpline(
x, knots = internal_knots, intercept = TRUE,
Boundary.knots = boundary_knots
),
times = 1e3,
unit = "relative"
)
```
Unit: relative
expr min lq mean median uq max neval cld
splines::ns 5.2152 4.9659 4.798 4.7187 4.6488 1.335 1000 b
splines2::naturalSpline 1.0000 1.0000 1.000 1.0000 1.0000 1.000 1000 a
The function `mSpline()` produces periodic spline basis functions (based
on M-splines) when `periodic = TRUE` is specified. The
`splines::periodicSpline()` returns a periodic interpolation spline
(based on B-splines) instead of basis matrix. Thus, we performed a
comparison with package **pbs** (version `r packageVersion("pbs")`),
where the function `pbs::pbs()` produces a basis matrix of periodic
B-spline by using `splines::spline.des()` (a wrapper function of
`splines::splineDesign()`).
``` r
microbenchmark(
"pbs::pbs" = pbs::pbs(x, knots = internal_knots, degree = degree,
intercept = TRUE, periodic = TRUE,
Boundary.knots = boundary_knots),
"splines2::mSpline" = mSpline(
x, knots = internal_knots, degree = degree, intercept = TRUE,
Boundary.knots = boundary_knots, periodic = TRUE
),
times = 1e3,
unit = "relative"
)
```
Unit: relative
expr min lq mean median uq max neval cld
pbs::pbs 3.465 3.2513 3.2501 3.1162 3.1062 3.4498 1000 b
splines2::mSpline 1.000 1.0000 1.0000 1.0000 1.0000 1.0000 1000 a
Session Information for Benchmarks
``` r
sessionInfo()
```
R version 4.1.0 (2021-05-18)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Arch Linux
Matrix products: default
BLAS: /usr/lib/libopenblasp-r0.3.17.so
LAPACK: /usr/lib/liblapack.so.3.10.0
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8
[4] LC_COLLATE=en_US.UTF-8 LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C LC_ADDRESS=C
[10] LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] splines stats graphics grDevices utils datasets methods base
other attached packages:
[1] splines2_0.4.5.9000 microbenchmark_1.4-7
loaded via a namespace (and not attached):
[1] Rcpp_1.0.7 mvtnorm_1.1-2 lattice_0.20-44 codetools_0.2-18 ibs_1.4
[6] zoo_1.8-9 digest_0.6.27 MASS_7.3-54 grid_4.1.0 magrittr_2.0.1
[11] evaluate_0.14 rlang_0.4.11 stringi_1.7.3 multcomp_1.4-17 Matrix_1.3-4
[16] sandwich_3.0-1 rmarkdown_2.10 TH.data_1.0-10 tools_4.1.0 stringr_1.4.0
[21] survival_3.2-11 xfun_0.25 yaml_2.2.1 compiler_4.1.0 pbs_1.1
[26] htmltools_0.5.1.1 knitr_1.33
## License
[GNU General Public License](https://www.gnu.org/licenses/) (≥ 3)
splines2/man/ 0000755 0001762 0000144 00000000000 14030134441 012556 5 ustar ligges users splines2/man/predict.Rd 0000644 0001762 0000144 00000004277 14013353332 014514 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/predict.R
\name{predict}
\alias{predict}
\alias{predict.bSpline2}
\alias{predict.dbs}
\alias{predict.ibs}
\alias{predict.mSpline}
\alias{predict.iSpline}
\alias{predict.cSpline}
\alias{predict.bernsteinPoly}
\alias{predict.naturalSpline}
\title{Evaluate a Spline Basis at specified points}
\usage{
\method{predict}{bSpline2}(object, newx, ...)
\method{predict}{dbs}(object, newx, ...)
\method{predict}{ibs}(object, newx, ...)
\method{predict}{mSpline}(object, newx, ...)
\method{predict}{iSpline}(object, newx, ...)
\method{predict}{cSpline}(object, newx, ...)
\method{predict}{bernsteinPoly}(object, newx, ...)
\method{predict}{naturalSpline}(object, newx, ...)
}
\arguments{
\item{object}{Objects of class \code{bSpline2}, \code{ibs}, \code{mSpline},
\code{iSpline}, \code{cSpline}, \code{bernsteinPoly} or
\code{naturalSpline} with attributes describing \code{knots},
\code{degree}, etc.}
\item{newx}{The \code{x} values at which evaluations are required.}
\item{...}{Optional arguments that are not used.}
}
\value{
An object just like the \code{object} input, except evaluated at
the new values of \code{x}.
}
\description{
This function evaluates a predefined spline basis at a (new) given \code{x}.
}
\details{
These are methods for the generic function \code{predict} for objects
inheriting from class \code{bSpline2}, \code{ibs}, \code{mSpline},
\code{iSpline}, \code{cSpline}, \code{naturalSpline}, or
\code{bernsteinPoly}. If \code{newx} is not given, the function returns the
input object.
}
\examples{
library(splines2)
x <- seq.int(0, 1, 0.2)
knots <- c(0.3, 0.5, 0.6)
newX <- seq.int(0.1, 0.9, 0.2)
## for B-splines
bsMat <- bSpline(x, knots = knots, degree = 2)
predict(bsMat, newX)
## for integral of B-splines
ibsMat <- ibs(x, knots = knots, degree = 2)
predict(ibsMat, newX)
## for derivative of B-splines
dbsMat <- dbs(x, knots = knots, degree = 2)
predict(dbsMat, newX)
## for M-spline
msMat <- mSpline(x, knots = knots, degree = 2)
predict(msMat, newX)
## for I-spline
isMat <- iSpline(x, knots = knots, degree = 2)
predict(isMat, newX)
## for C-spline
csMat <- cSpline(x, knots = knots, degree = 2)
predict(csMat, newX)
}
splines2/man/splines2.Rd 0000644 0001762 0000144 00000002756 14106352275 014631 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/splines2-package.R
\docType{package}
\name{splines2}
\alias{splines2}
\title{splines2: Regression Spline Functions and Classes}
\description{
This package provides functions to construct basis matrices of
\itemize{
\item B-splines
\item M-splines
\item I-splines
\item convex splines (C-splines)
\item periodic M-splines
\item natural cubic splines
\item generalized Bernstein polynomials
\item along with their integrals (except C-splines) and derivatives
of given order by closed-form recursive formulas
}
}
\details{
In addition to the R interface, it also provides a C++ header-only library
integrated with \pkg{Rcpp}, which allows the construction of spline basis
functions directly in C++ with the help of \pkg{Rcpp} and
\pkg{RcppArmadillo}. Thus, it can also be treated as one of the \pkg{Rcpp*}
packages. A toy example package that uses the C++ interface is available at
.
The package \pkg{splines2} is intended to be a user-friendly supplement to
the base package \pkg{splines}. The trailing number two in the package name
means "too" (and by no means refers to the generation two). See Wang and
Yan (2021) for details and illustrations of how the package can be applied
to shape-restricted regression.
}
\references{
Wang, W., & Yan, J. (2021). Shape-restricted regression splines with R
package \pkg{splines2}. \emph{Journal of Data Science}, 19(3), 498--517.
}
splines2/man/naturalSpline.Rd 0000644 0001762 0000144 00000010257 14014343037 015700 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/naturalSpline.R
\name{naturalSpline}
\alias{naturalSpline}
\title{Natural Cubic Spline Basis for Polynomial Splines}
\usage{
naturalSpline(
x,
df = NULL,
knots = NULL,
intercept = FALSE,
Boundary.knots = NULL,
derivs = 0L,
integral = FALSE,
...
)
}
\arguments{
\item{x}{The predictor variable. Missing values are allowed and will be
returned as they are.}
\item{df}{Degree of freedom that equals to the column number of returned
matrix. One can specify \code{df} rather than \code{knots}, then the
function chooses \code{df - 1 - as.integer(intercept)} internal knots at
suitable quantiles of \code{x} ignoring missing values and those
\code{x} outside of the boundary. Thus, \code{df} must be greater than
or equal to \code{2}. If internal knots are specified via \code{knots},
the specified \code{df} will be ignored.}
\item{knots}{The internal breakpoints that define the splines. The default
is \code{NULL}, which results in a basis for ordinary polynomial
regression. Typical values are the mean or median for one knot,
quantiles for more knots.}
\item{intercept}{If \code{TRUE}, the complete basis matrix will be returned.
Otherwise, the first basis will be excluded from the output.}
\item{Boundary.knots}{Boundary points at which to anchor the splines. By
default, they are the range of \code{x} excluding \code{NA}. If both
\code{knots} and \code{Boundary.knots} are supplied, the basis
parameters do not depend on \code{x}. Data can extend beyond
\code{Boundary.knots}.}
\item{derivs}{A nonnegative integer specifying the order of derivatives of
natural splines. The default value is \code{0L} for the spline basis
functions.}
\item{integral}{A logical value. The default value is \code{FALSE}. If
\code{TRUE}, this function will return the integrated natural splines
from the left boundary knot.}
\item{...}{Optional arguments that are not used.}
}
\value{
A numeric matrix of \code{length(x)} rows and \code{df}
columns if \code{df} is specified or \code{length(knots) + 1 +
as.integer(intercept)} columns if \code{knots} are specified instead.
Attributes that correspond to the arguments specified are returned for
usage of other functions in this package.
}
\description{
Generates the nonnegative natural cubic spline basis matrix, the
corresponding integrals (from the left boundary knot), or derivatives of
given order. Each basis is assumed to follow a linear trend for \code{x}
outside of boundary.
}
\details{
It is an implementation of the natural spline basis based on B-spline basis,
which utilizes the close-form null space that can be derived from the
recursive formula for the second derivatives of B-splines. The constructed
spline basis functions are intended to be nonnegative within boundary with
second derivatives being zeros at boundary knots.
A similar implementation is provided by \code{splines::ns}, which uses QR
decomposition to find the null space of the second derivatives of B-spline
basis at boundary knots. However, there is no guarantee that the resulting
basis functions are nonnegative within boundary.
}
\examples{
library(splines2)
x <- seq.int(0, 1, 0.01)
knots <- c(0.3, 0.5, 0.6)
## natural spline basis
nsMat0 <- naturalSpline(x, knots = knots, intercept = TRUE)
## integrals
nsMat1 <- naturalSpline(x, knots = knots, intercept = TRUE, integral = TRUE)
## first derivatives
nsMat2 <- naturalSpline(x, knots = knots, intercept = TRUE, derivs = 1)
## second derivatives
nsMat3 <- naturalSpline(x, knots = knots, intercept = TRUE, derivs = 2)
op <- par(mfrow = c(2, 2), mar = c(2.5, 2.5, 0.2, 0.1), mgp = c(1.5, 0.5, 0))
matplot(x, nsMat0, type = "l", ylab = "basis")
matplot(x, nsMat1, type = "l", ylab = "integral")
matplot(x, nsMat2, type = "l", ylab = "1st derivative")
matplot(x, nsMat3, type = "l", ylab = "2nd derivative")
par(op) # reset to previous plotting settings
## use the deriv method
all.equal(nsMat0, deriv(nsMat1), check.attributes = FALSE)
all.equal(nsMat2, deriv(nsMat0))
all.equal(nsMat3, deriv(nsMat2))
all.equal(nsMat3, deriv(nsMat0, 2))
}
\seealso{
\code{\link{bSpline}} for B-splines;
\code{\link{mSpline}} for M-splines;
\code{\link{iSpline}} for I-splines.
}
splines2/man/deriv.Rd 0000644 0001762 0000144 00000006437 14030134441 014170 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/deriv.R
\name{deriv}
\alias{deriv}
\alias{deriv.bSpline2}
\alias{deriv.dbs}
\alias{deriv.ibs}
\alias{deriv.mSpline}
\alias{deriv.iSpline}
\alias{deriv.cSpline}
\alias{deriv.bernsteinPoly}
\alias{deriv.naturalSpline}
\title{Derivatives of Spline Basis Functions}
\usage{
\method{deriv}{bSpline2}(expr, derivs = 1L, ...)
\method{deriv}{dbs}(expr, derivs = 1L, ...)
\method{deriv}{ibs}(expr, derivs = 1L, ...)
\method{deriv}{mSpline}(expr, derivs = 1L, ...)
\method{deriv}{iSpline}(expr, derivs = 1L, ...)
\method{deriv}{cSpline}(expr, derivs = 1L, ...)
\method{deriv}{bernsteinPoly}(expr, derivs = 1L, ...)
\method{deriv}{naturalSpline}(expr, derivs = 1L, ...)
}
\arguments{
\item{expr}{Objects of class \code{bSpline2}, \code{ibs}, \code{mSpline},
\code{iSpline}, \code{cSpline}, \code{bernsteinPoly} or
\code{naturalSpline} with attributes describing \code{knots},
\code{degree}, etc.}
\item{derivs}{A positive integer specifying the order of derivatives. By
default, it is \code{1L} for the first derivatives.}
\item{...}{Optional arguments that are not used.}
}
\value{
A numeric matrix of the same dimension with the input \code{expr}.
}
\description{
Returns derivatives of given order for the given spline basis functions.
}
\details{
At knots, the derivative is defined to be the right derivative except at the
right boundary knot. By default, the function returns the first derivatives.
For derivatives of order greater than one, nested function calls such as
\code{deriv(deriv(expr))} are supported but not recommended. For a better
performance, argument \code{derivs} should be specified instead.
This function is designed for objects produced by this package. It
internally extracts necessary specification about the spline/polynomial
basis matrix from its attributes. Therefore, the function will not work if
the key attributes are not available after some operations.
}
\examples{
library(splines2)
x <- c(seq.int(0, 1, 0.1), NA) # NA's will be kept.
knots <- c(0.3, 0.5, 0.6)
## helper function
stopifnot_equivalent <- function(...) {
stopifnot(all.equal(..., check.attributes = FALSE))
}
## integal of B-splines and the corresponding B-splines integrated
ibsMat <- ibs(x, knots = knots)
bsMat <- bSpline(x, knots = knots)
## the first derivative
d1Mat <- deriv(ibsMat)
stopifnot_equivalent(bsMat, d1Mat)
## the second derivative
d2Mat1 <- deriv(bsMat)
d2Mat2 <- deriv(ibsMat, derivs = 2L)
stopifnot_equivalent(d2Mat1, d2Mat2)
## nested calls are supported
d2Mat3 <- deriv(deriv(ibsMat))
stopifnot_equivalent(d2Mat2, d2Mat3)
## C-splines, I-splines, M-splines and the derivatives
csMat <- cSpline(x, knots = knots, intercept = TRUE, scale = FALSE)
isMat <- iSpline(x, knots = knots, intercept = TRUE)
stopifnot_equivalent(isMat, deriv(csMat))
msMat <- mSpline(x, knots = knots, intercept = TRUE)
stopifnot_equivalent(msMat, deriv(isMat))
stopifnot_equivalent(msMat, deriv(csMat, 2))
stopifnot_equivalent(msMat, deriv(deriv(csMat)))
dmsMat <- mSpline(x, knots = knots, intercept = TRUE, derivs = 1)
stopifnot_equivalent(dmsMat, deriv(msMat))
stopifnot_equivalent(dmsMat, deriv(isMat, 2))
stopifnot_equivalent(dmsMat, deriv(deriv(isMat)))
stopifnot_equivalent(dmsMat, deriv(csMat, 3))
stopifnot_equivalent(dmsMat, deriv(deriv(deriv(csMat))))
}
splines2/man/cSpline.Rd 0000644 0001762 0000144 00000010350 14103555677 014464 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/cSpline.R
\name{cSpline}
\alias{cSpline}
\title{C-Spline Basis for Polynomial Splines}
\usage{
cSpline(
x,
df = NULL,
knots = NULL,
degree = 3L,
intercept = TRUE,
Boundary.knots = NULL,
derivs = 0L,
scale = TRUE,
...
)
}
\arguments{
\item{x}{The predictor variable. Missing values are allowed and will be
returned as they are.}
\item{df}{Degree of freedom that equals to the column number of the returned
matrix. One can specify \code{df} rather than \code{knots}, then the
function chooses \code{df - degree - as.integer(intercept)} internal
knots at suitable quantiles of \code{x} ignoring missing values and
those \code{x} outside of the boundary. If internal knots are specified
via \code{knots}, the specified \code{df} will be ignored.}
\item{knots}{The internal breakpoints that define the splines. The default
is \code{NULL}, which results in a basis for ordinary polynomial
regression. Typical values are the mean or median for one knot,
quantiles for more knots.}
\item{degree}{The degree of C-spline defined to be the degree of the
associated M-spline instead of actual polynomial degree. For example,
C-spline basis of degree 2 is defined as the scaled double integral of
associated M-spline basis of degree 2.}
\item{intercept}{If \code{TRUE} by default, all of the spline basis
functions are returned. Notice that when using C-Spline for
shape-restricted regression, \code{intercept = TRUE} should be set even
when an intercept term is considered additional to the spline basis in
the model.}
\item{Boundary.knots}{Boundary points at which to anchor the splines. By
default, they are the range of \code{x} excluding \code{NA}. If both
\code{knots} and \code{Boundary.knots} are supplied, the basis
parameters do not depend on \code{x}. Data can extend beyond
\code{Boundary.knots}.}
\item{derivs}{A nonnegative integer specifying the order of derivatives of
C-splines. The default value is \code{0L} for C-spline basis functions.}
\item{scale}{A logical value indicating if scaling C-splines is required. If
\code{TRUE} by default, each C-spline basis is scaled to have unit
height at right boundary knot. The corresponding I-spline and M-spline
produced by \code{deriv} methods will be scaled to the same extent.}
\item{...}{Optional arguments that are not used.}
}
\value{
A numeric matrix of \code{length(x)} rows and \code{df} columns if
\code{df} is specified or \code{length(knots) + degree +
as.integer(intercept)} columns if \code{knots} are specified instead.
Attributes that correspond to the arguments specified are returned
mainly for other functions in this package.
}
\description{
Generates the convex regression spline (called C-spline) basis matrix by
integrating I-spline basis for a polynomial spline or the corresponding
derivatives.
}
\details{
It is an implementation of the closed-form C-spline basis derived from the
recursion formula of I-splines and M-splines.
}
\examples{
library(splines2)
x <- seq.int(0, 1, 0.01)
knots <- c(0.3, 0.5, 0.6)
### when 'scale = TRUE' (by default)
csMat <- cSpline(x, knots = knots, degree = 2)
op <- par(mar = c(2.5, 2.5, 0.2, 0.1), mgp = c(1.5, 0.5, 0))
matplot(x, csMat, type = "l", ylab = "C-spline basis")
abline(v = knots, lty = 2, col = "gray")
isMat <- deriv(csMat)
msMat <- deriv(csMat, derivs = 2)
matplot(x, isMat, type = "l", ylab = "scaled I-spline basis")
matplot(x, msMat, type = "l", ylab = "scaled M-spline basis")
## reset to previous plotting settings
par(op)
### when 'scale = FALSE'
csMat <- cSpline(x, knots = knots, degree = 2, scale = FALSE)
## the corresponding I-splines and M-splines (with same arguments)
isMat <- iSpline(x, knots = knots, degree = 2)
msMat <- mSpline(x, knots = knots, degree = 2, intercept = TRUE)
## or using deriv methods (more efficient)
isMat1 <- deriv(csMat)
msMat1 <- deriv(csMat, derivs = 2)
## equivalent
stopifnot(all.equal(isMat, isMat1, check.attributes = FALSE))
stopifnot(all.equal(msMat, msMat1, check.attributes = FALSE))
}
\references{
Meyer, M. C. (2008). Inference using shape-restricted regression splines.
\emph{The Annals of Applied Statistics}, 2(3), 1013--1033.
}
\seealso{
\code{\link{iSpline}} for I-splines;
\code{\link{mSpline}} for M-splines.
}
splines2/man/knots.Rd 0000644 0001762 0000144 00000003365 14013354053 014216 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/knots.R
\name{knots}
\alias{knots}
\alias{knots.bSpline2}
\alias{knots.dbs}
\alias{knots.ibs}
\alias{knots.mSpline}
\alias{knots.iSpline}
\alias{knots.cSpline}
\alias{knots.bernsteinPoly}
\alias{knots.naturalSpline}
\title{Extract Knots from the Given Object}
\usage{
\method{knots}{bSpline2}(Fn, type = c("internal", "boundary"), ...)
\method{knots}{dbs}(Fn, type = c("internal", "boundary"), ...)
\method{knots}{ibs}(Fn, type = c("internal", "boundary"), ...)
\method{knots}{mSpline}(Fn, type = c("internal", "boundary"), ...)
\method{knots}{iSpline}(Fn, type = c("internal", "boundary"), ...)
\method{knots}{cSpline}(Fn, type = c("internal", "boundary"), ...)
\method{knots}{bernsteinPoly}(Fn, type = c("internal", "boundary"), ...)
\method{knots}{naturalSpline}(Fn, type = c("internal", "boundary"), ...)
}
\arguments{
\item{Fn}{An \code{splines2} object produced by this package.}
\item{type}{A character vector of length one indicating the type of knots to
return. The available choices are \code{"internal"} for internal knots
and \code{"Boundary"} for boundary knots.}
\item{...}{Optional arguments that are not used now.}
}
\value{
A numerical vector.
}
\description{
Methods for the generic function \code{knots} from the \pkg{stats} package
to obtain internal or boundary knots from the objects produced by this
package.
}
\examples{
library(splines2)
set.seed(123)
x <- rnorm(100)
## B-spline basis
bsMat <- bSpline(x, df = 8, degree = 3)
## extract internal knots placed based on the quantile of x
(internal_knots <- knots(bsMat))
## extract boundary knots placed based on the range of x
boundary_knots <- knots(bsMat, type = "boundary")
all.equal(boundary_knots, range(x))
}
splines2/man/ibs.Rd 0000644 0001762 0000144 00000006037 14076105150 013635 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/ibs.R
\name{ibs}
\alias{ibs}
\title{Integrals of B-Splines}
\usage{
ibs(
x,
df = NULL,
knots = NULL,
degree = 3,
intercept = FALSE,
Boundary.knots = NULL,
...
)
}
\arguments{
\item{x}{The predictor variable. Missing values are allowed and will be
returned as they are.}
\item{df}{Degree of freedom that equals to the column number of the returned
matrix. One can specify \code{df} rather than \code{knots}, then the
function chooses \code{df - degree - as.integer(intercept)} internal
knots at suitable quantiles of \code{x} ignoring missing values and
those \code{x} outside of the boundary. If internal knots are specified
via \code{knots}, the specified \code{df} will be ignored.}
\item{knots}{The internal breakpoints that define the splines. The default
is \code{NULL}, which results in a basis for ordinary polynomial
regression. Typical values are the mean or median for one knot,
quantiles for more knots.}
\item{degree}{A nonnegative integer specifying the degree of the piecewise
polynomial. The default value is \code{3} for cubic splines. Zero degree
is allowed for piecewise constant basis functions.}
\item{intercept}{If \code{TRUE}, the complete basis matrix will be returned.
Otherwise, the first basis will be excluded from the output.}
\item{Boundary.knots}{Boundary points at which to anchor the splines. By
default, they are the range of \code{x} excluding \code{NA}. If both
\code{knots} and \code{Boundary.knots} are supplied, the basis
parameters do not depend on \code{x}. Data can extend beyond
\code{Boundary.knots}.}
\item{...}{Optional arguments that are not used.}
}
\value{
A numeric matrix of \code{length(x)} rows and \code{df} columns if
\code{df} is specified or \code{length(knots) + degree +
as.integer(intercept)} columns if \code{knots} are specified instead.
Attributes that correspond to the arguments specified are returned
mainly for other functions in this package.
}
\description{
Generates basis matrix for integrals of B-splines.
}
\details{
The implementation is based on the closed-form recursion formula.
}
\examples{
library(splines2)
x <- seq.int(0, 1, 0.01)
knots <- c(0.2, 0.4, 0.7, 0.9)
ibsMat <- ibs(x, knots = knots, degree = 1, intercept = TRUE)
## get the corresponding B-splines by bSpline()
bsMat0 <- bSpline(x, knots = knots, degree = 1, intercept = TRUE)
## or by the deriv() method
bsMat <- deriv(ibsMat)
stopifnot(all.equal(bsMat0, bsMat, check.attributes = FALSE))
## plot B-spline basis with their corresponding integrals
op <- par(mfrow = c(1, 2))
matplot(x, bsMat, type = "l", ylab = "B-spline basis")
abline(v = knots, lty = 2, col = "gray")
matplot(x, ibsMat, type = "l", ylab = "Integral of B-spline basis")
abline(v = knots, lty = 2, col = "gray")
## reset to previous plotting settings
par(op)
}
\references{
De Boor, Carl. (1978). \emph{A practical guide to splines}.
Vol. 27. New York: Springer-Verlag.
}
\seealso{
\code{\link{bSpline}} for B-splines;
\code{\link{dbs}} for derivatives of B-splines;
}
splines2/man/dbs.Rd 0000644 0001762 0000144 00000006357 14076105150 013635 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/dbs.R
\name{dbs}
\alias{dbs}
\title{Derivatives of B-Splines}
\usage{
dbs(
x,
derivs = 1L,
df = NULL,
knots = NULL,
degree = 3L,
intercept = FALSE,
Boundary.knots = NULL,
...
)
}
\arguments{
\item{x}{The predictor variable. Missing values are allowed and will be
returned as they are.}
\item{derivs}{A positive integer specifying the order of derivative. The
default value is \code{1L} for the first derivative.}
\item{df}{Degree of freedom that equals to the column number of the returned
matrix. One can specify \code{df} rather than \code{knots}, then the
function chooses \code{df - degree - as.integer(intercept)} internal
knots at suitable quantiles of \code{x} ignoring missing values and
those \code{x} outside of the boundary. If internal knots are specified
via \code{knots}, the specified \code{df} will be ignored.}
\item{knots}{The internal breakpoints that define the splines. The default
is \code{NULL}, which results in a basis for ordinary polynomial
regression. Typical values are the mean or median for one knot,
quantiles for more knots.}
\item{degree}{A nonnegative integer specifying the degree of the piecewise
polynomial. The default value is \code{3} for cubic splines. Zero degree
is allowed for piecewise constant basis functions.}
\item{intercept}{If \code{TRUE}, the complete basis matrix will be returned.
Otherwise, the first basis will be excluded from the output.}
\item{Boundary.knots}{Boundary points at which to anchor the splines. By
default, they are the range of \code{x} excluding \code{NA}. If both
\code{knots} and \code{Boundary.knots} are supplied, the basis
parameters do not depend on \code{x}. Data can extend beyond
\code{Boundary.knots}.}
\item{...}{Optional arguments that are not used.}
}
\value{
A numeric matrix of \code{length(x)} rows and \code{df} columns if
\code{df} is specified or \code{length(knots) + degree +
as.integer(intercept)} columns if \code{knots} are specified instead.
Attributes that correspond to the arguments specified are returned
mainly for other functions in this package.
}
\description{
Produces the derivatives of given order of B-splines.
}
\details{
This function provides a more user-friendly interface and a more consistent
handling for \code{NA}'s than \code{splines::splineDesign()} for derivatives
of B-splines. The implementation is based on the closed-form recursion
formula. At knots, the derivative is defined to be the right derivative
except at the right boundary knot.
}
\examples{
library(splines2)
x <- seq.int(0, 1, 0.01)
knots <- c(0.2, 0.4, 0.7)
## the second derivative of cubic B-splines with three internal knots
dMat <- dbs(x, derivs = 2L, knots = knots, intercept = TRUE)
## compare with the results from splineDesign
ord <- attr(dMat, "degree") + 1L
bKnots <- attr(dMat, "Boundary.knots")
aKnots <- c(rep(bKnots[1L], ord), knots, rep(bKnots[2L], ord))
res <- splines::splineDesign(aKnots, x = x, derivs = 2L)
stopifnot(all.equal(res, dMat, check.attributes = FALSE))
}
\references{
De Boor, Carl. (1978). \emph{A practical guide to splines}.
Vol. 27. New York: Springer-Verlag.
}
\seealso{
\code{\link{bSpline}} for B-splines;
\code{\link{ibs}} for integrals of B-splines.
}
splines2/man/bernsteinPoly.Rd 0000644 0001762 0000144 00000005476 14103555677 015741 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/bernsteinPoly.R
\name{bernsteinPoly}
\alias{bernsteinPoly}
\title{Generalized Bernstein Polynomial Basis}
\usage{
bernsteinPoly(
x,
degree = 3,
intercept = FALSE,
Boundary.knots = NULL,
derivs = 0L,
integral = FALSE,
...
)
}
\arguments{
\item{x}{The predictor variable taking values inside of the specified
boundary. Missing values are allowed and will be returned as they are.}
\item{degree}{A nonnegative integer representing the degree of the
polynomials.}
\item{intercept}{If \code{TRUE}, the complete basis matrix will be returned.
Otherwise, the first basis will be excluded from the output.}
\item{Boundary.knots}{Boundary points at which to anchor the Bernstein
polynomial basis. The default value is \code{NULL} and the boundary
knots is set internally to be \code{range(x, na.rm = TRUE)}.}
\item{derivs}{A nonnegative integer specifying the order of derivatives.
The default value is \code{0L} for Bernstein polynomial basis functions.}
\item{integral}{A logical value. If \code{TRUE}, the integrals of the
Bernstein polynomials will be returned. The default value is
\code{FALSE}.}
\item{...}{Optional arguments that are not used.}
}
\value{
A numeric matrix of dimension \code{length(x)} by \code{degree +
as.integer(intercept)}.
}
\description{
Returns a generalized Bernstein polynomial basis matrix of given degree over
a specified range.
}
\examples{
library(splines2)
x1 <- seq.int(0, 1, 0.01)
x2 <- seq.int(- 2, 2, 0.01)
## Bernstein polynomial basis matrix over [0, 1]
bMat1 <- bernsteinPoly(x1, degree = 4, intercept = TRUE)
## generalized Bernstein polynomials basis over [- 2, 2]
bMat2 <- bernsteinPoly(x2, degree = 4, intercept = TRUE)
op <- par(mfrow = c(1, 2), mar = c(2.5, 2.5, 0.2, 0.1), mgp = c(1.5, 0.5, 0))
matplot(x1, bMat1, type = "l", ylab = "y")
matplot(x2, bMat2, type = "l", ylab = "y")
## the first and second derivative matrix
d1Mat1 <- bernsteinPoly(x1, degree = 4, derivs = 1, intercept = TRUE)
d2Mat1 <- bernsteinPoly(x1, degree = 4, derivs = 2, intercept = TRUE)
d1Mat2 <- bernsteinPoly(x2, degree = 4, derivs = 1, intercept = TRUE)
d2Mat2 <- bernsteinPoly(x2, degree = 4, derivs = 2, intercept = TRUE)
par(mfrow = c(2, 2))
matplot(x1, d1Mat1, type = "l", ylab = "y")
matplot(x2, d1Mat2, type = "l", ylab = "y")
matplot(x1, d2Mat1, type = "l", ylab = "y")
matplot(x2, d2Mat2, type = "l", ylab = "y")
## reset to previous plotting settings
par(op)
## or use the deriv method
all.equal(d1Mat1, deriv(bMat1))
all.equal(d2Mat1, deriv(bMat1, 2))
## the integrals
iMat1 <- bernsteinPoly(x1, degree = 4, integral = TRUE, intercept = TRUE)
iMat2 <- bernsteinPoly(x2, degree = 4, integral = TRUE, intercept = TRUE)
all.equal(deriv(iMat1), bMat1, check.attributes = FALSE)
all.equal(deriv(iMat2), bMat2, check.attributes = FALSE)
}
splines2/man/bSpline.Rd 0000644 0001762 0000144 00000007003 14102414367 014451 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/bSpline.R
\name{bSpline}
\alias{bSpline}
\title{B-Spline Basis for Polynomial Splines}
\usage{
bSpline(
x,
df = NULL,
knots = NULL,
degree = 3L,
intercept = FALSE,
Boundary.knots = NULL,
derivs = 0L,
integral = FALSE,
...
)
}
\arguments{
\item{x}{The predictor variable. Missing values are allowed and will be
returned as they are.}
\item{df}{Degree of freedom that equals to the column number of the returned
matrix. One can specify \code{df} rather than \code{knots}, then the
function chooses \code{df - degree - as.integer(intercept)} internal
knots at suitable quantiles of \code{x} ignoring missing values and
those \code{x} outside of the boundary. If internal knots are specified
via \code{knots}, the specified \code{df} will be ignored.}
\item{knots}{The internal breakpoints that define the splines. The default
is \code{NULL}, which results in a basis for ordinary polynomial
regression. Typical values are the mean or median for one knot,
quantiles for more knots.}
\item{degree}{A nonnegative integer specifying the degree of the piecewise
polynomial. The default value is \code{3} for cubic splines. Zero degree
is allowed for piecewise constant basis functions.}
\item{intercept}{If \code{TRUE}, the complete basis matrix will be returned.
Otherwise, the first basis will be excluded from the output.}
\item{Boundary.knots}{Boundary points at which to anchor the splines. By
default, they are the range of \code{x} excluding \code{NA}. If both
\code{knots} and \code{Boundary.knots} are supplied, the basis
parameters do not depend on \code{x}. Data can extend beyond
\code{Boundary.knots}.}
\item{derivs}{A nonnegative integer specifying the order of derivatives of
B-splines. The default value is \code{0L} for B-spline basis functions.}
\item{integral}{A logical value. If \code{TRUE}, the corresponding
integrals of spline basis functions will be returned. The default value
is \code{FALSE}.}
\item{...}{Optional arguments that are not used.}
}
\value{
A numeric matrix of \code{length(x)} rows and \code{df} columns if
\code{df} is specified or \code{length(knots) + degree +
as.integer(intercept)} columns if \code{knots} are specified instead.
Attributes that correspond to the arguments specified are returned
mainly for other functions in this package.
}
\description{
Generates the B-spline basis matrix representing the family of piecewise
polynomials with the specified interior knots, degree, and boundary knots,
evaluated at the values of \code{x}.
}
\details{
This function extends the \code{bs()} function in the \code{splines} package
for B-spline basis by allowing piecewise constant (left-closed and
right-open except on the right boundary) spline basis of degree zero.
}
\examples{
library(splines2)
x <- seq.int(0, 1, 0.01)
knots <- c(0.3, 0.5, 0.6)
## cubic B-splines
bsMat <- bSpline(x, knots = knots, degree = 3, intercept = TRUE)
op <- par(mar = c(2.5, 2.5, 0.2, 0.1), mgp = c(1.5, 0.5, 0))
matplot(x, bsMat, type = "l", ylab = "Cubic B-splines")
abline(v = knots, lty = 2, col = "gray")
## reset to previous plotting settings
par(op)
## the first derivaitves
d1Mat <- deriv(bsMat)
## the second derivaitves
d2Mat <- deriv(bsMat, 2)
## evaluate at new values
predict(bsMat, c(0.125, 0.801))
}
\references{
De Boor, Carl. (1978). \emph{A practical guide to splines}.
Vol. 27. New York: Springer-Verlag.
}
\seealso{
\code{\link{dbs}} for derivatives of B-splines;
\code{\link{ibs}} for integrals of B-splines;
}
splines2/man/iSpline.Rd 0000644 0001762 0000144 00000006536 14103555677 014505 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/iSpline.R
\name{iSpline}
\alias{iSpline}
\title{I-Spline Basis for Polynomial Splines}
\usage{
iSpline(
x,
df = NULL,
knots = NULL,
degree = 3L,
intercept = TRUE,
Boundary.knots = NULL,
derivs = 0L,
...
)
}
\arguments{
\item{x}{The predictor variable. Missing values are allowed and will be
returned as they are.}
\item{df}{Degree of freedom that equals to the column number of the returned
matrix. One can specify \code{df} rather than \code{knots}, then the
function chooses \code{df - degree - as.integer(intercept)} internal
knots at suitable quantiles of \code{x} ignoring missing values and
those \code{x} outside of the boundary. If internal knots are specified
via \code{knots}, the specified \code{df} will be ignored.}
\item{knots}{The internal breakpoints that define the splines. The default
is \code{NULL}, which results in a basis for ordinary polynomial
regression. Typical values are the mean or median for one knot,
quantiles for more knots.}
\item{degree}{The degree of I-spline defined to be the degree of the
associated M-spline instead of actual polynomial degree. For example,
I-spline basis of degree 2 is defined as the integral of associated
M-spline basis of degree 2.}
\item{intercept}{If \code{TRUE} by default, all of the spline basis
functions are returned. Notice that when using I-Spline for monotonic
regression, \code{intercept = TRUE} should be set even when an intercept
term is considered additional to the spline basis functions.}
\item{Boundary.knots}{Boundary points at which to anchor the splines. By
default, they are the range of \code{x} excluding \code{NA}. If both
\code{knots} and \code{Boundary.knots} are supplied, the basis
parameters do not depend on \code{x}. Data can extend beyond
\code{Boundary.knots}.}
\item{derivs}{A nonnegative integer specifying the order of derivatives of
I-splines.}
\item{...}{Optional arguments that are not used.}
}
\value{
A numeric matrix of \code{length(x)} rows and \code{df} columns if
\code{df} is specified or \code{length(knots) + degree +
as.integer(intercept)} columns if \code{knots} are specified instead.
Attributes that correspond to the arguments specified are returned
mainly for other functions in this package.
}
\description{
Generates the I-spline (integral of M-spline) basis matrix for a polynomial
spline or the corresponding derivatives of given order.
}
\details{
It is an implementation of the closed-form I-spline basis based on the
recursion formula given by Ramsay (1988).
}
\examples{
library(splines2)
## Example given in the reference paper by Ramsay (1988)
x <- seq.int(0, 1, by = 0.01)
knots <- c(0.3, 0.5, 0.6)
isMat <- iSpline(x, knots = knots, degree = 2)
op <- par(mar = c(2.5, 2.5, 0.2, 0.1), mgp = c(1.5, 0.5, 0))
matplot(x, isMat, type = "l", ylab = "I-spline basis")
abline(v = knots, lty = 2, col = "gray")
## reset to previous plotting settings
par(op)
## the derivative of I-splines is M-spline
msMat1 <- iSpline(x, knots = knots, degree = 2, derivs = 1)
msMat2 <- mSpline(x, knots = knots, degree = 2, intercept = TRUE)
stopifnot(all.equal(msMat1, msMat2))
}
\references{
Ramsay, J. O. (1988). Monotone regression splines in action.
\emph{Statistical Science}, 3(4), 425--441.
}
\seealso{
\code{\link{mSpline}} for M-splines;
\code{\link{cSpline}} for C-splines;
}
splines2/man/mSpline.Rd 0000644 0001762 0000144 00000015347 14102414367 014476 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/mSpline.R
\name{mSpline}
\alias{mSpline}
\title{M-Spline Basis for Polynomial Splines}
\usage{
mSpline(
x,
df = NULL,
knots = NULL,
degree = 3L,
intercept = FALSE,
Boundary.knots = NULL,
periodic = FALSE,
derivs = 0L,
integral = FALSE,
...
)
}
\arguments{
\item{x}{The predictor variable. Missing values are allowed and will be
returned as they are.}
\item{df}{Degree of freedom that equals to the column number of the returned
matrix. One can specify \code{df} rather than \code{knots}. For
M-splines, the function chooses \code{df - degree -
as.integer(intercept)} internal knots at suitable quantiles of \code{x}
ignoring missing values and those \code{x} outside of the boundary. For
periodic M-spline (\code{periodic = TRUE}), \code{df -
as.integer(intercept)} internal knots will be chosen at suitable
quantiles of \code{x} relative to the beginning of the cyclic intervals
they belong to (see Examples) and the number of internal knots must be
greater or equal to the specified \code{degree - 1}. If internal knots
are specified via \code{knots}, the specified \code{df} will be ignored.}
\item{knots}{The internal breakpoints that define the splines. The default
is \code{NULL}, which results in a basis for ordinary polynomial
regression. Typical values are the mean or median for one knot,
quantiles for more knots. For periodic splines (\code{periodic =
TRUE}), the number of knots must be greater or equal to the specified
\code{degree - 1}.}
\item{degree}{A nonnegative integer specifying the degree of the piecewise
polynomial. The default value is \code{3} for cubic splines. Zero degree
is allowed for piecewise constant basis functions.}
\item{intercept}{If \code{TRUE}, the complete basis matrix will be returned.
Otherwise, the first basis will be excluded from the output.}
\item{Boundary.knots}{Boundary points at which to anchor the splines. By
default, they are the range of \code{x} excluding \code{NA}. If both
\code{knots} and \code{Boundary.knots} are supplied, the basis
parameters do not depend on \code{x}. Data can extend beyond
\code{Boundary.knots}. For periodic splines (\code{periodic = TRUE}),
the specified boundary knots define the cyclic interval.}
\item{periodic}{A logical value. If \code{TRUE}, the periodic splines will
be returned instead of regular M-splines. The default value is
\code{FALSE}.}
\item{derivs}{A nonnegative integer specifying the order of derivatives of
M-splines. The default value is \code{0L} for M-spline basis functions.}
\item{integral}{A logical value. If \code{TRUE}, the corresponding
integrals of spline basis functions will be returned. The default value
is \code{FALSE}. For periodic splines, the integral of each basis is
integrated from the left boundary knot.}
\item{...}{Optional arguments that are not used.}
}
\value{
A numeric matrix of \code{length(x)} rows and \code{df} columns if
\code{df} is specified. If \code{knots} are specified instead, the
output matrix will consist of \code{length(knots) + degree +
as.integer(intercept)} columns if \code{periodic = FALSE}, or
\code{length(knots) + as.integer(intercept)} columns if \code{periodic =
TRUE}. Attributes that correspond to the arguments specified are
returned for usage of other functions in this package.
}
\description{
Generates the basis matrix of regular M-spline, periodic M-spline, and the
corresponding integrals and derivatives.
}
\details{
This function contains an implementation of the closed-form M-spline basis
based on the recursion formula given by Ramsay (1988) or periodic M-spline
basis following the procedure producing periodic B-splines given in Piegl
and Tiller (1997). For monotone regression, one can use I-splines (see
\code{\link{iSpline}}) instead of M-splines.
}
\examples{
library(splines2)
### example given in the reference paper by Ramsay (1988)
x <- seq.int(0, 1, 0.01)
knots <- c(0.3, 0.5, 0.6)
msMat <- mSpline(x, knots = knots, degree = 2, intercept = TRUE)
op <- par(mar = c(2.5, 2.5, 0.2, 0.1), mgp = c(1.5, 0.5, 0))
matplot(x, msMat, type = "l", ylab = "y")
abline(v = knots, lty = 2, col = "gray")
## derivatives of M-splines
dmsMat <- mSpline(x, knots = knots, degree = 2,
intercept = TRUE, derivs = 1)
## or using the deriv method
dmsMat1 <- deriv(msMat)
stopifnot(all.equal(dmsMat, dmsMat1, check.attributes = FALSE))
### periodic M-splines
x <- seq.int(0, 3, 0.01)
bknots <- c(0, 1)
pMat <- mSpline(x, knots = knots, degree = 3, intercept = TRUE,
Boundary.knots = bknots, periodic = TRUE)
## integrals
iMat <- mSpline(x, knots = knots, degree = 3, intercept = TRUE,
Boundary.knots = bknots, periodic = TRUE, integral = TRUE)
## first derivatives by "derivs = 1"
dMat1 <- mSpline(x, knots = knots, degree = 3, intercept = TRUE,
Boundary.knots = bknots, periodic = TRUE, derivs = 1)
## first derivatives by using the deriv() method
dMat2 <- deriv(pMat)
par(mfrow = c(2, 2))
matplot(x, pMat, type = "l", ylab = "Periodic Basis")
abline(v = seq.int(0, max(x)), lty = 2, col = "grey")
matplot(x, iMat, type = "l", ylab = "Integrals from 0")
abline(v = seq.int(0, max(x)), h = seq.int(0, max(x)), lty = 2, col = "grey")
matplot(x, dMat1, type = "l", ylab = "1st derivatives by 'derivs=1'")
abline(v = seq.int(0, max(x)), lty = 2, col = "grey")
matplot(x, dMat2, type = "l", ylab = "1st derivatives by 'deriv()'")
abline(v = seq.int(0, max(x)), lty = 2, col = "grey")
## reset to previous plotting settings
par(op)
### default placement of internal knots for periodic splines
default_knots <- function(x, df, intercept = FALSE,
Boundary.knots = range(x, na.rm = TRUE)) {
## get x in the cyclic interval [0, 1)
x2 <- (x - Boundary.knots[1]) \%\% (Boundary.knots[2] - Boundary.knots[1])
knots <- quantile(x2, probs = seq(0, 1, length.out = df + 2 - intercept))
unname(knots[- c(1, length(knots))])
}
df <- 8
degree <- 3
intercept <- TRUE
internal_knots <- default_knots(x, df, intercept)
## 1. specify df
spline_basis1 = splines2::mSpline(x, degree = degree, df = df,
periodic = TRUE, intercept = intercept)
## 2. specify knots
spline_basis2 = splines2::mSpline(x, degree = degree, knots = internal_knots,
periodic = TRUE, intercept = intercept)
all.equal(internal_knots, knots(spline_basis1))
all.equal(spline_basis1, spline_basis2)
}
\references{
Ramsay, J. O. (1988). Monotone regression splines in action.
\emph{Statistical science}, 3(4), 425--441.
Piegl, L., & Tiller, W. (1997). \emph{The NURBS book}. Springer Science \&
Business Media.
}
\seealso{
\code{\link{bSpline}} for B-splines;
\code{\link{iSpline}} for I-splines;
\code{\link{cSpline}} for C-splines.
}
splines2/DESCRIPTION 0000644 0001762 0000144 00000002650 14121634402 013517 0 ustar ligges users Package: splines2
Title: Regression Spline Functions and Classes
Version: 0.4.5
Authors@R: c(
person(given = "Wenjie", family = "Wang",
email = "wang@wwenjie.org",
role = c("aut", "cre"),
comment = c(ORCID = "0000-0003-0363-3180")),
person(given = "Jun", family = "Yan", role = "aut",
comment = c(ORCID = "0000-0003-4401-7296"))
)
Description: Constructs basis matrix of B-splines, M-splines,
I-splines, convex splines (C-splines), periodic M-splines,
natural cubic splines, generalized Bernstein polynomials,
and their integrals (except C-splines) and derivatives
of given order by close-form recursive formulas.
It also contains a C++ head-only library integrated with Rcpp.
See Wang and Yan (2021) for details.
Imports: Rcpp, stats
LinkingTo: Rcpp, RcppArmadillo
Suggests: knitr, rmarkdown, tinytest
Depends: R (>= 3.2.3)
VignetteBuilder: knitr
License: GPL (>= 3)
URL: https://wwenjie.org/splines2,
https://github.com/wenjie2wang/splines2
BugReports: https://github.com/wenjie2wang/splines2/issues
Encoding: UTF-8
RoxygenNote: 7.1.1
NeedsCompilation: yes
Packaged: 2021-09-19 00:33:10 UTC; wenjie
Author: Wenjie Wang [aut, cre] (),
Jun Yan [aut] ()
Maintainer: Wenjie Wang
Repository: CRAN
Date/Publication: 2021-09-19 13:20:02 UTC
splines2/build/ 0000755 0001762 0000144 00000000000 14121502506 013104 5 ustar ligges users splines2/build/vignette.rds 0000644 0001762 0000144 00000000362 14121502506 015444 0 ustar ligges users uO]0i
dA|7D*jl_]m4~sAe@44=G6(2Bn