为GLMM Bootstrap函数添加判断:模型不收敛时设结果为NA
解决GLMM Bootstrap抽样中的模型不收敛问题
问题分析
你的Bootstrap函数存在两个核心问题:
- 拼写错误:
summary$coefficeints应为summary$coefficients,会导致正常拟合时也无法提取系数 - 未处理模型不收敛和抽样数据中的缺失值,导致部分抽样失败
下面提供两种可直接使用的解决方案:
方案1:不收敛时返回NA值
该方案在模型拟合失败(不收敛/报错)时,返回全NA的结果向量,最终Bootstrap结果中保留这些NA,后续可根据需求自行过滤。
library(lme4) library(data.table) hormonedf <- as.data.table(hormonedf) sexsteroidbootstrap <- function(df, n) { # 按个体有放回抽样 samp <- sample(unique(df$ID), n, replace = TRUE) setkey(df, "ID") df_sample <- df[J(samp), allow.cartesian = TRUE] # 过滤Behaviors列的缺失值,避免拟合报错 df_sample <- df_sample[!is.na(Behaviors), ] # 尝试拟合模型,捕获错误与收敛警告 model <- tryCatch( glmer(formula = Behaviors ~ 1 + Age + Treatment + Age:Treatment + (1|ID), data = df_sample, family=poisson), error = function(e) NULL, warning = function(w) { # 识别收敛类警告,标记为拟合失败 if(grepl("convergence", w$message)) NULL else w } ) # 若拟合失败,返回全NA向量 if(is.null(model)) { return(rep(NA, 11)) } # 提取系数与p值 summary_mod <- summary(model) coef_mat <- summary_mod$coefficients return(c( coef_mat[1,1], coef_mat[2,1], coef_mat[3,1], coef_mat[4,1], coef_mat[5,1], coef_mat[6,1], coef_mat[2,4], coef_mat[3,4], coef_mat[4,4], coef_mat[5,4], coef_mat[6,4] )) } # 执行Bootstrap bootstrapresults <- as.data.frame(replicate(1000, sexsteroidbootstrap(hormonedf, 29))) bootstrapresults <- t(bootstrapresults) bootstrapresults <- as.data.frame(bootstrapresults) # 为结果列命名(可选) colnames(bootstrapresults) <- c("Intercept", "Age_Coef", "EE_Coef", "KT_Coef", "EEAge_Coef", "KTAge_Coef", "pAge", "pEE", "pKT", "pEEAge", "pKTAge")
方案2:跳过不收敛抽样,重新抽样直到成功
该方案会自动重新抽样,直到得到能成功拟合的模型,最终结果中无NA值,保证获得指定数量的有效Bootstrap样本。
library(lme4) library(data.table) hormonedf <- as.data.table(hormonedf) sexsteroidbootstrap <- function(df, n) { while(TRUE) { # 按个体有放回抽样 samp <- sample(unique(df$ID), n, replace = TRUE) setkey(df, "ID") df_sample <- df[J(samp), allow.cartesian = TRUE] # 过滤缺失值 df_sample <- df_sample[!is.na(Behaviors), ] # 尝试拟合模型 model <- tryCatch( glmer(formula = Behaviors ~ 1 + Age + Treatment + Age:Treatment + (1|ID), data = df_sample, family=poisson), error = function(e) NULL, warning = function(w) { if(grepl("convergence", w$message)) NULL else w } ) # 拟合成功则提取结果并返回,否则循环重新抽样 if(!is.null(model)) { summary_mod <- summary(model) coef_mat <- summary_mod$coefficients return(c( coef_mat[1,1], coef_mat[2,1], coef_mat[3,1], coef_mat[4,1], coef_mat[5,1], coef_mat[6,1], coef_mat[2,4], coef_mat[3,4], coef_mat[4,4], coef_mat[5,4], coef_mat[6,4] )) } } } # 执行Bootstrap bootstrapresults <- as.data.frame(replicate(1000, sexsteroidbootstrap(hormonedf, 29))) bootstrapresults <- t(bootstrapresults) bootstrapresults <- as.data.frame(bootstrapresults) # 为结果列命名(可选) colnames(bootstrapresults) <- c("Intercept", "Age_Coef", "EE_Coef", "KT_Coef", "EEAge_Coef", "KTAge_Coef", "pAge", "pEE", "pKT", "pEEAge", "pKTAge")
关键说明
- 缺失值处理:抽样后先移除
Behaviors列的NA,避免因缺失值导致的基础拟合错误 - 错误捕获逻辑:用
tryCatch识别模型拟合时的错误和收敛警告,将拟合失败的模型标记为无效 - 拼写修正:修复了原代码中
coefficeints的拼写错误,确保系数提取正常运行 - 方案选择:若需保留所有抽样记录(含失败样本)选方案1;若需严格获得指定数量的有效结果选方案2
内容的提问来源于stack exchange,提问作者Molly Westbrook
相关产品推荐
相关产品推荐

