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?