我目前正在尝试使用x
包中的协变量gamm
(年龄)和性别0-1变量与mgcv
之间的互动进行建模。在为每个性别指定一个具有平滑术语的主模型(让我们称之为M0
)后,我想测试一个更简单的假设,即性别之间的差异是线性的(而不是任意平滑)。我有以下两个问题:
M0
中获得0-性别平滑的平滑参数,并在更简单的模型规范中使用它。但是我收到以下错误消息:gamm.setup出错(gp,pterms = pTerms,data = mf,knots = knots,parametric.only = FALSE,:
gamm无法处理链接的平滑参数(可能来自使用`id'或自适应平滑)
下面是一个例子。我模拟了一些随机数据,因此数据不会显示我实际数据的行为,但问题仍然存在。
library(mgcv)
### Simulate random data
x <- rnorm(100, mean = 10, sd = 1.5)
y <- rnorm(100, mean = 1, sd = 0.025)
id <- sample(1:10, size = 100, replace = T)
id <- as.factor(id)
gender <- sample(c(0,1), size = 100, replace = T)
### Specify main model, M0
ctrl <- list(niterEM=0,optimMethod="L-BFGS-B", msMaxIter = 100)
M0 <- gamm(y~s(x, by = as.factor(gender)) + gender,
random=list(id=~1+x), control=ctrl)
### Specify model with linear difference between gender0 and gender1
M1 <- gamm(y~s(x) + gender:x + gender,
random=list(id=~1+x), control=ctrl)
### Testing
anova(M0$lme, M1$lme)
### Problems:
sp0 <- M0$gam$sp[1]
M1 <- gamm(y~s(x, sp = sp0) + gender:x + gender,
random=list(id=~1+x), control=ctrl)
gamm.setup出错(gp,pterms = pTerms,data = mf,knots = knots,parametric.only = FALSE,:
gamm无法处理链接的平滑参数(可能来自使用`id'或自适应平滑)
有什么想法?提前谢谢。
答案 0 :(得分:3)
gamm
错误这是一件非常有趣的事情......好吧,我应该首先解释逻辑。
原则上在gamm
中修复平滑参数是违法的,因为gamm
会将平滑的摇摆组件视为随机效果,其方差为由lme
估算(因为你有高斯数据)。如果您尝试修复平滑参数,那基本上就是说要修复随机效果的方差。好吧,lme
不允许你这样做(我怀疑这种尝试在混合建模中是否合法。)
因此gamm
会禁用平滑参数的任何可能限制,包括:
min.sp
; id
; s()
链接平滑共享相同的平滑参数
sp
直接指定平滑参数,通过s()
。前两个完美检查。 gamm
没有像min.sp
那样的gam
参数;即使您通过...
指定它,也不会被使用(因为在NULL
期间传递给gam.setup
的{{1}}之后,所以您的指定{{1}被忽略了)。您看到的错误消息也会检测到gamm.setup
的规范,但当然您没有指定min.sp
,因此上述错误并未在此处报告正确的问题,因此存在错误。
第三个,实际上并未通过id
直接检查。理想情况下,只要id
/ gamm
公式被解释(gamm
),gam
就应该重置为interpret.gam
,如果不是,应发出关于此的警告信息。但是,这部分缺失了。因此,目前您可以做的最好的事情就是不指定sp
。
现在让我们转向您对嵌套的关注。 嵌套与基础设置有关,而不是平滑参数的选择。只要您具有相同的基础集(相同的基础类型,相同数量和/或位置的“结”),模型矩阵将是相同的。例如,在您的模型-1
和sp
中,您具有与M0
默认M1
s()
相同的配置。因此mgcv
的设计矩阵在两个模型中是相同的。 bs = 'tp', k = 10
只会将此s()
复制到主模型by = factor(gender)
中s()
的所有级别。也许它不容易看到,但实际上您的gender
嵌套在M0
。
让我们考虑一个小例子来验证这一点。为简单起见,我不会使用M1
中的M0
,而是使用s(x)
(想象它是mgcv
)。让我们先生成一些玩具数据:
poly(x, degree = 2)
由于s(x)
不是有序因子,x <- 1:10
f <- gl(2, 5, labels = c("M", "F"))
通过为f
的所有级别复制s(x, by = factor(f))
来生成设计矩阵:
s(x)
您的第二个模型f
只有一个平滑的术语## original design matrix for `s(x)`
X0 <- poly(x, 2)
## design matrix for `f`, without contrasting
Xf <- model.matrix(~ f + 0)
## design matrix for level `M`
X1 <- X0 * Xf[, 1]
## design matrix for level `F`
X2 <- X0 * Xf[, 2]
## design matrix for `s(x, by = f)` "please, imagine it as `poly`"
X <- cbind(X1, X2)
# 1 2 1 2
# [1,] -0.49543369 0.52223297 0.00000000 0.00000000
# [2,] -0.38533732 0.17407766 0.00000000 0.00000000
# [3,] -0.27524094 -0.08703883 0.00000000 0.00000000
# [4,] -0.16514456 -0.26111648 0.00000000 0.00000000
# [5,] -0.05504819 -0.34815531 0.00000000 0.00000000
# [6,] 0.00000000 0.00000000 0.05504819 -0.34815531
# [7,] 0.00000000 0.00000000 0.16514456 -0.26111648
# [8,] 0.00000000 0.00000000 0.27524094 -0.08703883
# [9,] 0.00000000 0.00000000 0.38533732 0.17407766
#[10,] 0.00000000 0.00000000 0.49543369 0.52223297
,其设计矩阵为M1
。
以下是我们如何看待您的s(x)
嵌套在X0
中:
M1
,M0
和X1 + X2 = X0
的设计矩阵具有相同的列范围,因此s(x)
嵌套在s(x, by = f)
; s(x)
嵌套在s(x, by = f)
中,x
嵌套在s(x)
中。虽然您的模型已经很好地嵌套,但主模型x:f
与您的s(x, by = f)
没有相似的解释。您的主要模型M0
最终将为每个级别提供一个独立的平滑,而您的M1
则关注两个组之间的差异。
如果我们能够控制M0
接受一种“参考平滑+差异平滑”的形式,那将是一件好事。然后,如果差异平滑变成一条线,而没有实际拟合M1
,我们已经知道没有证据表明组之间存在非线性差异。
在M0
中,如果您的因子是有序的,则将构建差异平滑。所以我建议你适合你的主要模型:
M1
如果估算结果显示差异平滑mgcv
为一条线,则您知道可以改为使用更简单的模型
gender1 <- ordered(gender) ## create an ordered factor
s(x) + s(x, by = gender1) + gender
即使不使用s(x, by = gender1)
。
注意,为了构造“差异”平滑,有一个有序因子s(x) + gender:x + gender
是非常重要的。如果你这样做
F-test
by
和s(x) + s(x, by = gender) + gender ## note, it is "gender" in "by"
完全线性相关。生成的模型矩阵将排名不足。
我忘了在我的示例中包含我首先将AIC参数化为
s(x)
和s(x, by = gender)
的相同模型进行比较(回忆s(x, by = as.factor(gender))
为0-1数值变量)。这些模型在统计上是等价的,但在这些情况下,平滑参数显然有不同的估计,因此AIC略有不同。
哦,是的。您的s(x) + s(x, by = gender)
是二进制的,因此数字gender
也是构建差异平滑的好主意。但要小心这样做。数字gender
不会产生居中的光滑。因此,by
将隐式地具有拦截列,与模型拦截混淆。你应该使用by
。