glmmLasso运行报错:数组不兼容及下标赋值含NA问题求助
问题描述
运行以下R代码时出现报错:
library(haven) library(survival) library(dplyr) library(readr) library(glmmLasso) par(mar=c(1,1,1,1)) library(discSurv) HH <- as.data.frame(read_dta("https://www.stata.com/data/jwooldridge/eacsap/recid.dta")) HHC <- contToDisc(dataShort = HH, timeColumn = "durat", intervalLimits = 20, equi = TRUE) dtLong <- dataLong(dataShort = HHC, timeColumn = "timeDisc", eventColumn = "cens", timeAsFactor = FALSE) formula.1 <- y~factor(black)+factor(alcohol) family <- binomial(link = "logit") lambda <- 20 penal.vec <- 20 next.try <- TRUE BIC_vec <- rep(Inf,length(lambda)) Deltama.glm2 <- as.matrix(t(rep(0,3)))#coefficients + Intercept Smooth.glm2 <- as.matrix(t(rep(0,20))) j <- 1;test.step <- 1; glm2 <- glmmLasso(formula.1, rnd = NULL,family = family, data = dtLong, lambda=lambda[j],final.re=T,switch.NR=F, control = list(smooth=list(formula=~-1+as.numeric(timeInt),nbasis=20,spline.degree=3, diff.ord=2,penal=penal.vec[test.step],start=Smooth.glm2[j,]), method.final="EM", print.iter=T,print.iter.final=T, eps.final=1e-4,epsilon=1e-4,complexity="non.zero", start=Deltama.glm2[j,]))
两种初始值设置下的报错
- 初始设置
Deltama.glm2<-as.matrix(t(rep(0,3)))时:
Iteration 41
Final Re-estimation Iteration 9Error in Z_aktuell * D : non-conformable arrays
- 修改为
Deltama.glm2<-as.matrix(t(rep(0,2)))后:
Iteration 1Error in grad.lasso[b.is.0] <- score.beta[b.is.0] - lambda.b * sign(score.beta[b.is.0]) :
NAs are not allowed in subscripted assignments
已尝试移除初始值,但问题仍未解决。
原因分析与解决方法
1. 初始值维度不匹配
公式y~factor(black)+factor(alcohol)对应的固定效应参数包括:截距项、factor(black)的1个哑变量参数、factor(alcohol)的1个哑变量参数,共3个参数。初始值Deltama.glm2长度设为2时,参数数量不足引发下标赋值NA错误;设为3时,报错核心出在平滑项的初始值与模型设置不兼容。
2. 平滑项设置冲突
control$smooth中设置nbasis=20,但dtLong的timeInt是离散时间区间,实际区间数量远小于20,导致样条基函数的设计矩阵与数据维度不匹配,引发数组相乘时的维度错误。
3. 分步解决步骤
确认固定效应参数数量
先运行基础glm模型确认参数个数,确保初始值长度匹配:base_glm <- glm(formula.1, family = family, data = dtLong) print(length(coef(base_glm))) # 应返回3 Deltama.glm2 <- matrix(rep(0, length(coef(base_glm))), nrow=1)调整平滑项设置
把nbasis设为数据中实际的时间区间数量,且移除自定义平滑项初始值,避免维度冲突:control = list(smooth=list(formula=~-1+as.numeric(timeInt), nbasis=length(unique(dtLong$timeInt)), spline.degree=3,diff.ord=2,penal=penal.vec[test.step]), method.final="EM", print.iter=T,print.iter.final=T, eps.final=1e-4,epsilon=1e-4,complexity="non.zero")简化初始设置
先去掉所有自定义初始值,让模型从默认值开始拟合,排除初始值干扰:glm2 <- glmmLasso(formula.1, rnd = NULL,family = family, data = dtLong, lambda=lambda[j],final.re=T,switch.NR=F, control = control)检查数据结构
确认长格式数据的变量是否正常生成,无缺失或异常值:str(dtLong) table(dtLong$y, dtLong$timeInt)
内容的提问来源于stack exchange,提问作者Magondo

