I am trying to fit a hurdle model to seasonal data for which the day of the year is known.
To this end, I tried to construct a spline with cyclic restrictions (ends meet beginnings). Here is a MWE using lm
instead of a hurdle model to simplify the problem:
# Example data
set.seed(1234)
n <- 1000
x <- runif(n, 0, 2 * pi) # some random time in the year (2 * pi being day 365)
y <- sin(x) + rnorm(n)
# Generate cyclic B-spline bases using mgcv
k <- 4
knots <- seq(0, 2 * pi, length.out = k)
cyclicSpline <- mgcv::cSplineDes(x, knots = knots)
However, if I try to use the resulting spline basis functions as predictors for my model, it ends up being rank deficient:
> lm(y ~ cyclicSpline)
Call:
lm(formula = y ~ cyclicSpline)
Coefficients:
(Intercept) cyclicSpline1 cyclicSpline2 cyclicSpline3 cyclicSpline4
-0.09211 -1.40510 0.03613 1.68947 NA
I tried orthogonalizing the spline basis functions, but this still results in rank deficiency:
> Q <- svd(t(cyclicSpline))$v
> lm(y ~ Q)
Call:
lm(formula = y ~ Q)
Coefficients:
(Intercept) Q1 Q2 Q3 Q4
8.173 258.817 -7.297 21.510 NA
I have also tried this with different numbers of knots, but it seems to always result in rank deficiency. I was under the impression that once orthogonalized, I end up with independent basis functions. If so, why does that result in a rank deficient design matrix?