You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于多重插补结果创建分类变量及被动插补报错问题咨询

问题描述

我有1000条样本数据,包含连续变量与分类变量,存在缺失值。需要基于多重插补后的结果,为每个样本标记class(class A、B、C)分类变量。

我首先参考《Flexible imputation of missing data, 2nd ed.》中6.4章节的方法尝试实现,代码如下:

imp1 <- mice(df, maxit = 5, pred = pred ,method =meth, post=post, print = TRUE, allow.na=TRUE)
    
long1 <- mice::complete(imp1, "long", include=TRUE)
    
long2<-long1 %>% 
       rowwise() %>% 
       mutate(class = case_when(sum(var1 == 1, var2 > 15, var3 == 1, var4 == 2, var5 < 2.0) >= 2 ~ 'class A',
                       sum(var1 == 1, var2 > 15, var3 == 1, var4 == 2, var5 < 2.0) == 1 &
                         sum((var2 >= 15 & var2 < 25), var4 == 1) > 1 ~ 'class B',
                       TRUE ~ 'class C'))
    
 imp1.itt <- as.mids(long2)  

Q1:请问该方法是否可行?

Q2:是否可以通过被动插补(passive imputation)实现?我尝试了以下代码:

df1<-cbind(df, class=NA)

ini<-mice(df1, max=0, print=FALSE)

pred<-ini$predictorMatrix
pred[, c( 'class')]<-0  

meth<-ini$method     
meth['class']<-"~case_when(sum(var1 == 1, var2 > 15, var3 == 1, var4 == 2, var5 < 2.0) >= 2 ~ 'class A',
                           sum(var1 == 1, var2 > 15, var3 == 1, var4 == 2, var5 < 2.0) == 1 &
                             sum((var2 >= 15 & var2 < 25), var4 == 1) > 1 ~ 'class B',
                           TRUE ~ 'class C')"

imp <- mice(df1, maxit = 5, predictorMatrix = pred,method =meth,  
            print =  TRUE, allow.na=TRUE)

但运行时出现错误:Error in colMeans(as.matrix(imp[[j]]), na.rm = TRUE) : 'x' must be numeric,请问问题出在哪里?

示例数据集

df2 <- read.table(text = "       var1    var2    var3    var4    var5
id1     1       10       1       0      1.5
id2     0       20       0       1      2.4
id3     0       15       0       1      3.5
id4     1       30       1       1      2.1", header = TRUE)

解答

Q1:方法可行性分析

该方法可行,但需注意几个细节:

  • rowwise()处理1000条数据效率尚可,若后续数据量增大,建议用rowSums()做向量化操作替代,减少逐行循环的开销。
  • as.mids(long2)要确保long格式中的.imp、.id列与原始插补的分组、样本ID对应,否则后续基于mids对象的分析可能出错。
  • 确认sum(var1 ==1,...)的逻辑:这里sum()会将布尔值转为1/0求和,逻辑正确,但要保证long1中无缺失值(complete(..., include=TRUE)已包含原始数据和所有插补数据集)。

Q2:被动插补报错原因与修正

报错原因

mice的被动插补(公式形式)默认期望生成数值型变量,而你的class是字符型分类变量,as.matrix(imp[[j]])会将字符型列转为因子或保留字符,导致colMeans()无法计算(仅支持数值型矩阵),因此抛出错误。

修正方案

有两种可行思路:

思路1:先编码为数值,插补后转回分类标签

df1<-cbind(df, class=NA)

ini<-mice(df1, max=0, print=FALSE)

pred<-ini$predictorMatrix
pred[, 'class']<-0  

# 先将分类逻辑转为数值编码
meth['class']<-"~{
  score1 <- sum(var1 == 1, var2 > 15, var3 == 1, var4 == 2, var5 < 2.0)
  score2 <- sum((var2 >=15 & var2 <25), var4 ==1)
  ifelse(score1 >=2, 1, ifelse(score1 ==1 & score2 >1, 2, 3))
}"

imp <- mice(df1, maxit =5, predictorMatrix=pred, method=meth, print=TRUE)

# 插补完成后将数值转回分类标签
imp$imp$class <- lapply(imp$imp$class, function(x) {
  factor(x, levels=c(1,2,3), labels=c('class A','class B','class C'))
})

思路2:自定义被动插补函数处理分类变量

mice允许自定义插补方法,针对分类变量写专属函数:

# 定义分类变量的被动插补函数
passive_class <- function(data, ...) {
  score1 <- rowSums(cbind(data$var1 ==1, data$var2 >15, data$var3 ==1, data$var4 ==2, data$var5 <2.0))
  score2 <- rowSums(cbind(data$var2 >=15 & data$var2 <25, data$var4 ==1))
  class <- case_when(
    score1 >=2 ~ 'class A',
    score1 ==1 & score2 >1 ~ 'class B',
    TRUE ~ 'class C'
  )
  return(class)
}

df1<-cbind(df, class=NA)

ini<-mice(df1, max=0, print=FALSE)

pred<-ini$predictorMatrix
pred[, 'class']<-0  

meth<-ini$method
meth['class'] <- "passive_class"

# 注册自定义方法
mice::mice.add.method("passive_class", passive_class, "Passive imputation for class variable", TRUE)

imp <- mice(df1, maxit=5, predictorMatrix=pred, method=meth, print=TRUE)

内容的提问来源于stack exchange,提问作者JY J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 19:02:27