多重插补:SMCFCS对象转MICE生成收敛绘图报错如何解决
报错原因
mice包自带的plot()(追踪收敛图)和densityplot()函数依赖mids对象中存储的每一轮迭代的插补值、链追踪数据,你通过miceadds::datlist2mids转换得到的mids对象仅保留了最终插补完成的数据集,缺失迭代过程的链信息,因此调用绘图函数时会报错。
解决方案
方案1:使用smcfcs原生诊断逻辑+手动绘图(更推荐)
smcfcs本身输出了迭代过程的模型系数序列可做收敛校验,插补值分布可直接遍历插补数据集绘制对比图,适配性更高:
# 1. 系数收敛校验:绘制每一轮迭代的Cox模型系数轨迹 # 绘制第1个插补链的系数迭代值,替换[,,2]可查看第2个链 matplot( db.imputed$smCoefIter[,,1], type = "l", lty = 1, xlab = "迭代轮数", ylab = "Cox模型系数值", main = "插补过程系数收敛图" ) legend("topright", legend = c("sex", "ph.ecog"), col = 1:2, lty = 1) # 2. 插补值密度校验:以age变量为例 library(ggplot2) # 提取所有插补数据集的age插补值 na_age_pos <- is.na(data$age) imp_age <- lapply(db.imputed$impDatasets, function(x) x$age[na_age_pos]) imp_age_df <- data.frame( value = unlist(imp_age), group = rep(paste0("插补链",1:length(imp_age)), each = length(imp_age[[1]])) ) # 加入原始非缺失age作为参考 obs_age_df <- data.frame(value = data$age[!na_age_pos], group = "原始观测") plot_df <- rbind(imp_age_df, obs_age_df) # 绘制密度对比图 ggplot(plot_df, aes(x = value, color = group)) + geom_density(linewidth = 1) + labs(x = "年龄", y = "密度", title = "age变量插补值与观测值密度对比") + theme_bw()
方案2:构造完整mids对象复用mice绘图工具
如果需要直接使用mice的绘图接口,可手动补全mids对象的缺失字段:
# 提取原始数据缺失位置 na_pos <- is.na(data) # 构造插补值列表 imp_list <- list() for (var in colnames(data)) { if (sum(na_pos[,var]) > 0) { imp_list[[var]] <- do.call(cbind, lapply(db.imputed$impDatasets, function(x) x[na_pos[,var], var])) colnames(imp_list[[var]]) <- paste0("Chain", 1:ncol(imp_list[[var]])) } } # 初始化mids对象 db.mice_full <- mice( data, m = length(db.imputed$impDatasets), maxit = db.imputed$numit, predictorMatrix = predMatrix, method = method, printFlag = FALSE ) # 替换插补值与迭代系数 db.mice_full$imp <- imp_list db.mice_full$chainMean <- apply(db.imputed$smCoefIter, c(3,1), as.vector) # 可正常调用mice绘图函数 densityplot(db.mice_full) plot(db.mice_full)
注意:smcfcs的插补迭代逻辑与mice存在差异,系数收敛性的参考价值高于插补值轨迹图,优先使用方案1做校验。
内容的提问来源于stack exchange,提问作者Rudolph
相关产品推荐
相关产品推荐

