如何解决R中nlme包lme()函数的MEEM奇异错误?
线性混合效应模型构建报错:Singularity in backsolve at level 0, block 1
我用nlme包的lme()函数构建线性混合效应模型,研究运动员反应时(rxn)与任务中需记忆数字数量(0、3、5、7、9、11位)的关系,数据框已编码各观测的对应条件。
当前代码:
ref_0_rxn <- lme(fixed = rxn ~ dig3+dig5+dig7+dig9+dig11+trial+c.hx, random = list(pt=~1), data = all_data_lmm, na.action = na.exclude, control = lmeControl(opt = "optim", maxIter = 200, msMaxIter = 200, niterEM = 50, msMaxEval = 400))
其中dig3至dig11是虚拟编码的条件变量,rxn为秒级反应时,c.hx是标记参与者是否有脑震荡史的二元变量,随机变量为参与者ID(已转成因子)。运行时出现错误:
Error in MEEM(object, conLin, control$niterEM) : Singularity in backsolve at level 0, block 1
我试过调整脑震荡史等二元变量和虚拟编码变量,看到博客说这个奇异错误和数值稳定性有关。只含截距的空模型能正常运行:
null_rxn <- lme(fixed = rxn ~ 1, random = list(pt=~1), data= all_data_lmm, na.action = na.exclude, control = lmeControl(opt = "optim", maxIter = 200, msMaxIter = 200, niterEM = 50, msMaxEval = 400))
问题应该出在新增的回归变量上,想问哪里操作错了?要不要改用lme4包的lmer()函数?
问题解答
1. 报错核心原因
这个奇异错误通常和固定效应变量的多重共线性或数值尺度差异过大直接相关:
- 你用
dig3-dig11作为虚拟变量,基准组是0位数字,需确认这些虚拟变量间是否存在完全共线性(比如某个digX变量与其他变量线性相关),或是部分参与者在特定条件下无观测值,导致变量矩阵秩不足。 trial这类连续变量如果数值范围过大,和0-1取值的虚拟变量、二元变量尺度差异悬殊,会严重影响模型求解的数值稳定性,进而导致矩阵不可逆。
2. 分步解决方法
- 排查多重共线性:用
cor()函数查看固定效应变量的相关系数,或用car包的vif()计算方差膨胀因子,若VIF>10说明存在严重共线性,需移除相关变量。 - 标准化连续变量:将
trial这类连续变量转为z分数(scale(trial)),缩小不同变量的尺度差异,提升数值稳定性。 - 逐步添加变量排查:先仅加入
dig3-dig11运行模型,确认正常后再逐个加入trial、c.hx,定位具体引发问题的变量。 - 调整lme控制参数:尝试降低
niterEM(比如设为10),或更换优化器(opt="nlminb"),过多迭代也可能引发数值异常。
3. 是否切换到lme4?
lme4的lmer()对数值不稳定情况的容忍度更高,且错误提示更直观,若调整后nlme仍报错,可以尝试切换。等价的lmer代码如下:
library(lme4) ref_0_rxn_lmer <- lmer(rxn ~ dig3+dig5+dig7+dig9+dig11+trial+c.hx + (1|pt), data = all_data_lmm, na.action = na.exclude)
不过建议优先排查变量本身的问题,再考虑换包。
内容的提问来源于stack exchange,提问作者domwill
相关产品推荐
相关产品推荐

