有一个标题相同的问题,但是,我希望这个问题也引起您的兴趣[并且我个人想知道答案]。
首先,我将指定一个具有一个连续和一个因子协变量的数据集:
set.seed(1)
n <- 50
u1 <- sample(c(1,2), n, replace = TRUE)
u1 <- factor(u1)
u2 <- runif(n)
data <- data.frame(u1, u2)
我不想运行gam
模型,而只是创建设计矩阵。我考虑过两种方法。
首先
a<-mgcv::s(u2,k=5,bs="ps",by=u1)
b<- mgcv::smoothCon(a,data=data,absorb.cons=TRUE)
但是,
b[[1]]$X[u1==2,]
仅包含0。
第二,
a<- mgcv::s(u1,u2,k=5,bs="ad")
b<- mgcv::smoothCon(a,data=data,absorb.cons=TRUE)
但是,它给我一条错误消息。 Error in Summary.factor(c(1L, 1L, 2L, 2L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, :
‘min’ not meaningful for factors
该问题如何解决?我希望有一个设计矩阵,可以为因子u1
的每个级别分别建模一个平滑项[二进制,如这里或其他]。
答案 0 :(得分:3)
我不想运行
gam
模型,而只是创建设计矩阵。我希望有一个设计矩阵,可以针对因子
u1
的每个级别分别对平滑项进行建模。
library(mgcv)
set.seed(1)
n <- 50
u1 <- sample(c(1,2), n, replace = TRUE)
u1 <- factor(u1)
u2 <- runif(n)
data <- data.frame(u1, u2)
a <- s(u2, k = 5, bs = "ps", by = u1)
b <- smoothCon(a, data = data, absorb.cons = TRUE)
smoothCon
生成一个长度nlevels(u1)
的列表,该列表“ by”平滑。为u1
创建了一个虚拟矩阵(此示例中有两列),并且每一列都与s(u2, l = 5, bs = "ps")
的设计矩阵相乘。因此,b[[1]]$X
是第一级的设计矩阵,b[[2]]$X
是第二级的设计矩阵。 b[[1]]$X[u1 == 2]
给出全零,您应该不会感到惊讶,因为这是u1 == 1
的设计矩阵。您想cbind
将这些单独的矩阵放在一起:
cbind(b[[1]]$X, b[[2]]$X)
请注意,因为已设置absorb.cons = TRUE
,所以样条函数居中。即,每个级别的平均值受到约束(不一定为0,而是固定为某个值)。实际的效果是,您随后需要将u1
放入模型中,否则无法对组均值建模。在mgcv
中,您必须指定
s(u2, k = 5, bs = 'ps', by = u1) + u1
在您引用的“问题与解答”中也提到了此问题:mgcv: how to specify interaction between smooth and factor?。在mgcv
以外的应用程序中,您也需要注意这一点。因此,完整的模型矩阵应该是
cbind(b[[1]]$X, b[[2]]$X, model.matrix(~ u1))