为glmer对象编写LOOCV函数时遇「无效分组因子DID」错误求助
解决glmer留一交叉验证(LOOCV)中的分组因子错误
问题描述
尝试为glmer对象实现留一交叉验证(LOOCV),使用UCLA的hdp示例数据,运行代码时出现错误:Error: Invalid grouping factor specification, DID。
错误原因分析
- 循环次数错误:代码中写了
for (i in 1:8825),但实际数据集行数仅为2530,超出范围的循环会导致空的验证集,引发数据异常。 - 数据筛选冗余:利用唯一行号筛选数据的写法冗余,且可能在极端情况下导致逻辑错误。
- 分组因子匹配问题:若某分组(DID)仅对应一个观测,当该观测作为验证集时,训练集中将不再包含该分组水平。使用默认
predict方法时,因模型中无该分组的随机效应信息,会触发分组因子错误;此外,拟合模型时若训练集中存在分组水平无观测的情况(虽LOOCV中少见,但循环次数错误可能导致),也会报错。 - R2计算错误:
remission是因子类型,直接参与数值运算会引发类型错误。
修正后的代码
# 加载所需包 library(tidyverse) library(optimx) library(lme4) # 导入并预处理示例数据 Data <- read.csv("https://stats.idre.ucla.edu/stat/data/hdp.csv") %>% select(remission, IL6, CRP, DID) %>% mutate( remission = as.factor(remission), DID = as.factor(DID), ROW = row_number() ) # 初始化预测结果向量 PTOT <- numeric(nrow(Data)) # 执行LOOCV循环 for (i in 1:nrow(Data)) { # 提取验证集(第i行) DataC1 <- Data[Data$ROW == i, ] # 提取训练集(除第i行外的所有数据) DataCV <- Data[Data$ROW != i, ] # 拟合glmer模型 M1 <- glmer(remission ~ 1 + IL6 + CRP + (1 | DID), data = DataCV, family = binomial, control = glmerControl(optimizer = 'optimx', optCtrl = list(method = 'L-BFGS-B'))) # 预测验证集:使用re.form=NA仅预测固定效应,避免分组不匹配问题 # 若需包含随机效应,需确保训练集包含验证集的DID水平(即该DID至少有2个观测) P1 <- predict(M1, DataC1, re.form = NA, type = "response") PTOT[i] <- P1 } # 计算CV-R2:先将因子转为数值(0/1) remission_num <- as.numeric(Data$remission) - 1 R2cv <- 1 - (sum((remission_num - PTOT)^2) / length(PTOT)) / var(remission_num) R2cv
关键修正点说明
- 循环次数:改为
1:nrow(Data),确保循环覆盖所有观测。 - 数据筛选:简化为直接通过行号判断,逻辑更清晰。
- 预测参数:添加
re.form = NA,仅基于固定效应预测,避免因验证集分组不在训练集中导致的错误;若业务需求必须包含随机效应,需先过滤掉仅含单个观测的分组(filter(Data, DID %in% names(table(Data$DID))[table(Data$DID) > 1]))。 - R2计算:将因子型的
remission转换为0/1数值,确保运算合法。
内容的提问来源于stack exchange,提问作者confusedindividual
相关产品推荐
相关产品推荐

