2
$\begingroup$

I am interested in understanding how does the splines2 library from R place the knots when computing periodic splines. I understand the logic when splines are not periodic, for example, I know that if the knots are not specified, the number of knots is equal to

$$knots = df - degree $$

where 'df' refers to the degrees of freedom of the spline basis, and 'degree' refers to the degree of the polinomial, and they are placed on the quantiles. For example:

library(splines2)
library(splines)

df = 8
degree = 3
x = seq(0, 1, length.out=15)

knots = seq(0, 1, length.out = df - degree + 2)
knots = knots[2:(length(knots)-1)]
# df - degree = length(knots)

spline_basis1 =  splines2::mSpline(x, degree=degree, df=df)
spline_basis2 =  splines2::mSpline(x, degree=degree, knots=knots)

spline_basis1 and spline_basis2 will return the same result. But if I consider periodic splines, this is no longer true:

# Periodic splines
spline_basis1 =  splines2::mSpline(x, degree=degree, df=df, periodic=T)
spline_basis2 =  splines2::mSpline(x, degree=degree, knots=knots, periodic=T) 

My guess is that when computing periodic splines, the number of parameters to be estimated (the degrees of freedom) is different, but I would like to understand how are knots placed by default when splines are periodic.

$\endgroup$
3
  • 1
    $\begingroup$ Doesn't the documentation answer that? $\endgroup$
    – whuber
    Commented Jul 12, 2021 at 12:45
  • 1
    $\begingroup$ The documentation (cran.r-project.org/web/packages/splines2/splines2.pdf) explains the number of knots chosen but not where they are placed. I took them based on the quantiles but obtain a different solution than the default one. $\endgroup$ Commented Jul 12, 2021 at 14:26
  • $\begingroup$ Thanks -- I see the documentation only states "... at suitable quantiles... ." The best way to obtain an answer is to inspect the source code. $\endgroup$
    – whuber
    Commented Jul 12, 2021 at 14:30

1 Answer 1

2
$\begingroup$

Your guess is correct. The relationship between the df and knots is df = length(knots) + as.integer(intercept) for periodic splines that implemented in splines2::mSpline(). For B-splines implemented in splines::bs() or splines2::bSpline(), the relationship is df = length(knots) + degree + as.integer(intercept).

See the following code for comparison:

df <- 8
degree <- 3
x <- seq(0, 1, length.out = 15)
x2 <- x %% 1       # get x in the cyclic period [0, 1)
intercept <- FALSE # default, the first basis function excluded

## set internal knots
knots <- quantile(x2, probs = seq(0, 1, length.out = df + 1 + (! intercept)))
(knots <- knots[- c(1, length(knots))])
#>  11.11111%  22.22222%  33.33333%  44.44444%  55.55556%  66.66667%  77.77778% 
#> 0.03968254 0.15079365 0.26190476 0.37301587 0.48412698 0.59523810 0.70634921 
#>  88.88889% 
#> 0.81746032

spline_basis1 =  splines2::mSpline(x, degree = degree, df = df,
                                   periodic = TRUE, intercept = intercept)
spline_basis2 =  splines2::mSpline(x, degree = degree, knots = knots,
                                   periodic = TRUE, intercept = intercept)

knots(spline_basis1)
#> [1] 0.03968254 0.15079365 0.26190476 0.37301587 0.48412698 0.59523810 0.70634921
#> [8] 0.81746032

all.equal(spline_basis1, spline_basis2)
#> [1] TRUE
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.