我对软件包“ splines”中的“ bs”功能有些困惑。源代码告诉我,当“ intercept = FALSE”时它将删除矩阵的第一列,但是当我尝试“ intercept = FALSE”时,它将给出具有相同列数的另一个矩阵(我希望原始矩阵的第一列没有被移除)。
我参考了JEFFREY S. RACINE编写的“回归样条上的底漆”,并对他的代码进行了一些调整,以编写自己的“ bspline”函数。当我将其与“ bs”函数进行比较时,我发现它们在“ intercept = FALSE”时返回相同的矩阵(均删除原始矩阵的第一列),而在“ intercept = TRUE”时返回不同的矩阵。
### my own function to define B-spline
basis <- function(x, degree, i, knots) {
if(degree == 0){
B <- ifelse((x >= knots[i]) & (x < knots[i+1]), 1, 0)
} else {
if((knots[degree+i] - knots[i]) == 0) {
alpha1 <- 0
} else {
alpha1 <- (x - knots[i])/(knots[degree+i] - knots[i])
}
if((knots[i+degree+1] - knots[i+1]) == 0) {
alpha2 <- 0
} else {
alpha2 <- (knots[i+degree+1] - x)/(knots[i+degree+1] - knots[i+1])
}
B <- alpha1*basis(x, (degree-1), i, knots) + alpha2*basis(x, (degree-1), (i+1), knots)
}
return(B)
}
bspline <- function(x, K=NULL, degree=3, interior.knots=NULL,
intercept=FALSE, Boundary.knots = range(x)) {
# The parameter K is the number of interior knots
if(degree < 1) stop("The spline degree must be at least 1")
if (is.null(K) && is.null(interior.knots)) stop("The parameter K and interior.knots must be given at least one")
if (!is.null(K) && is.null(interior.knots)) {
interior.knots <- if (K > 0L) {
interior.knots <- seq.int(from = 0, to = 1, length.out = K+2L)[-c(1L, K + 2L)]
quantile(x, interior.knots)
}
}
if(!is.null(K) && (K<length(interior.knots))){
warning("K<length(interior.knots)")
}
knots <- sort(c(rep(Boundary.knots, (degree+1)), interior.knots))
n <- length(interior.knots) + degree + 1 # number of control points
B.mat <- matrix(0,length(x),n)
for(i in 1:n) B.mat[,i] <- basis(x, degree, i, knots)
if(any(x == Boundary.knots[2])) B.mat[x == Boundary.knots[2], n] <- 1
if(intercept == FALSE) {
return(B.mat[,-1])
} else {
return(B.mat)
}
}
### compare bs function and my bspline function
library("splines")
t <- sort(runif(600,0,1))
Bf <- bs(t, df=6, degree=3, intercept = FALSE)
BF <- bspline(t,K=3,degree=3,intercept = FALSE)
Bt <- bs(t, df=6, degree=3, intercept = TRUE)
BT <- bspline(t,K=3,degree=3,intercept = TRUE)
### same results when "intercept = FALSE"
Bf[1:10,1];BF[1:10,1];BT[1:10,2];
### different results when "intercept = TRUE"
Bt[1:10,1];BT[1:10,1];
dim(Bt)[2];dim(BT)[2];
我期望dim(Bt)[2]的输出为7,但实际输出为6。 实际上,我希望Bt = BT。