《应用纵向分析(第二版)》官网nlme::gls示例代码运行结果不符问询
问题原因分析
- 核心问题1:固定效应设定存在完全共线性
gls默认包含截距项,原代码中I(week.f==1) + I(week.f==4) + I(week.f==6)三个指示变量的和恒等于1,和截距项完全线性相关,导致设计矩阵秩亏,触发奇异报错。你添加singular.ok = TRUE后R会自动丢弃一列共线变量(通常是最后一个I(week.f==6)),所以输出会缺失week.f=6的主效应,系数估计也全部失真。 - 核心问题2:数据筛选逻辑与官网模型不一致
原代码中tlclong <- subset(tlclong, time > 1)删除了基线(time=1,对应y0)的所有观测,100名受试者每人剩余3次随访观测,总样本量为300,对应你输出的300自由度。官网示例保留了基线作为随访时间点,总样本量为400,相关结构为4×4的非结构化矩阵,方差参数也多1个基线水平的估计值,这就是你看到的相关矩阵维度少1、缺少0类方差输出、自由度不符的核心原因。 - 其他潜在影响因素
代码中使用attach(tlclong)会将数据集变量挂载到全局环境,如果你之前的工作环境中存在同名的time、week等变量,会导致赋值逻辑出错,进一步放大结果偏差。
修正方案
要复现官网结果可以按如下方式调整代码:
- 若官网模型确实排除基线、仅分析3次随访数据:删除默认截距避免共线性,同时避免使用
attach减少变量冲突:
library(foreign) library(nlme) ds <- read.dta("tlc.dta") ds$baseline <- ds$y0 tlclong <- reshape(ds, idvar="id", varying=c("y0","y1","y4","y6"),v.names="y", timevar="time", time=1:4, direction="long") tlclong <- subset(tlclong, time > 1) # 直接在数据集内操作,避免变量冲突 tlclong$week <- tlclong$time tlclong$week[tlclong$time==2] <- 1 tlclong$week[tlclong$time==3] <- 4 tlclong$week[tlclong$time==4] <- 6 tlclong$time <- tlclong$time - 1 tlclong$week.f <- factor(tlclong$week, c(1,4,6)) # 固定效应去掉截距避免共线性,写法更简洁 model <- gls(y ~ 0 + week.f + week.f:trt, data = tlclong, corr=corSymm(form= ~ time | id), weights = varIdent(form = ~ 1 | week.f)) summary(model)
- 若官网模型包含基线观测:删除
subset(tlclong, time > 1)这行代码,对应调整week和week.f的赋值逻辑,加入基线水平即可。
内容的提问来源于stack exchange,提问作者James Cutler
相关产品推荐
相关产品推荐

