线性混合模型加入time二次项后收敛失败问题求助
线性混合模型二次项拟合收敛失败问题
问题背景
使用给定数据集拟合线性混合模型时,纳入time线性项的模型可正常收敛,但纳入poly(time,2)二次项时出现报错:
Error in lme.formula(vas ~ poly(time, 2), random = ~poly(time, 2) | nhc, : optim problem, convergence error code = 1
已知有3个有效时间点,理论上二次项模型可行,且线性项未报错,排除单纯样本量问题。已尝试调整迭代次数(msMaxIter、msMaxEval)但无效,现提出两个问题:
- 导致收敛失败的语法或数据原因是什么?
- 能否在代码中捕获该错误并跳过,或处理
time==2的情况?
相关代码
# 线性项模型(正常收敛) lme(vas ~ time, random= ~ time|nhc, control = lmeControl(opt = "optim"), method="REML", data=df, na.action = na.omit) # 二次项模型(报错) lme(vas ~ poly(time, 2), random= ~ poly(time,2)|nhc, control = lmeControl(opt = "optim"), method="REML", data=df, na.action = na.omit)
数据集
df <-structure(list(nhc = structure(c(20121491, 20121491, 20121491, 20121491, 20121491, 19217499, 19217499, 19217499, 19217499, 19217499, 20336737, 20336737, 20336737, 20336737, 20336737, 14682006, 14682006, 14682006, 14682006, 14682006, 18454625, 18454625, 18454625, 18454625, 18454625, 20109250, 20109250, 20109250, 20109250, 20109250, 19117092, 19117092, 19117092, 19117092, 19117092, 12618871, 12618871, 12618871, 12618871, 12618871, 19620863, 19620863, 19620863, 19620863, 19620863, 18190617, 18190617, 18190617, 18190617, 18190617, 15286988, 15286988, 15286988, 15286988, 15286988, 521462, 521462, 521462, 521462, 521462, 19434947, 19434947, 19434947, 19434947, 19434947, 20841801, 20841801, 20841801, 20841801, 20841801, 19788686, 19788686, 19788686, 19788686, 19788686, 12574473, 12574473, 12574473, 12574473, 12574473, 15294473, 15294473, 15294473, 15294473, 15294473), format.spss = "F8.0"), time = c(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5), vas = c(5, 4, 4, NA, NA, NA, NA, NA, NA, NA, 5, NA, 4, NA, NA, 5, 1, 1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 4, 2, 2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 5, NA, NA, NA, NA, 5, 4, NA, NA, NA, 9, NA, 3, NA, NA, 5, 2, 2, NA, NA)), row.names = c(NA, -85L), class = c("tbl_df", "tbl", "data.frame"))
问题解答
1. 收敛失败的原因
数据层面
- 有效样本量极度不足:看似有3个有效时间点,但实际数据集里大部分个体的
vas值都是NA,最终仅6个个体有至少2个非NA的vas值。二次项模型的随机部分需要估计3个参数(截距、time线性项、time二次项),参数数量远超有效支撑数据,导致优化器无法找到稳定的极值点。 - 共线性与稀疏数据叠加:
poly(time,2)生成的正交多项式在时间点数量少时,易和其他项产生隐性共线性,再加上数据稀疏,进一步放大了优化难度。 - 优化器适配性差:指定
opt="optim"(默认Nelder-Mead方法)在处理稀疏数据时稳定性不如默认的nlminb,后者对参数空间的搜索效率更适合这类场景。
模型设定层面
- 随机结构过于复杂:
~poly(time,2)|nhc要求每个个体都有截距、线性项、二次项的随机效应,对稀疏数据而言,这种复杂结构极易导致参数估计不稳定,直接引发收敛失败。
2. 错误捕获与数据处理方案
错误捕获
用tryCatch()函数捕获拟合错误,失败时跳过或返回替代结果:
# 封装带错误捕获的拟合函数 fit_model <- function(model_formula, random_formula, data) { result <- tryCatch({ lme(model_formula, random = random_formula, control = lmeControl(opt = "nlminb"), # 换用更稳定的优化器 method="REML", data=data, na.action = na.omit) }, error = function(e) { message("模型拟合失败:", e$message) return(NULL) # 失败时返回NULL }) return(result) } # 拟合二次项模型 quad_model <- fit_model(vas ~ poly(time,2), ~poly(time,2)|nhc, df) # 拟合成功后再执行后续分析 if (!is.null(quad_model)) { summary(quad_model) }
针对time==2的数据处理
- 筛选包含
time==2的有效个体:
library(dplyr) # 保留至少有time==2且vas非NA的个体 df_filtered <- df %>% group_by(nhc) %>% filter(any(time==2 & !is.na(vas))) %>% ungroup() # 用筛选后的数据拟合模型 quad_model_filtered <- tryCatch({ lme(vas ~ poly(time,2), ~poly(time,2)|nhc, control = lmeControl(opt = "nlminb"), method="REML", data=df_filtered, na.action = na.omit) }, error = function(e) NULL)
- 简化随机结构:如果不需要每个个体都有二次项随机效应,可简化为
~time|nhc,降低模型复杂度,大幅提升收敛概率。
内容的提问来源于stack exchange,提问作者Javier Hernando
相关产品推荐
相关产品推荐

