为什么bs(x,intercept = FALSE)和bs(x,intercept = TRUE)给出的基样条数相同?

时间:2019-04-16 12:42:11

标签: r bspline

我对软件包“ 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。

0 个答案:

没有答案