多重插补后合并Cronbach's Alpha计算报错求助
多重插补后计算Cronbach's Alpha报错排查与解决
问题背景
使用mice()完成多重插补(m=20、maxit=10),合并两个插补数据集并转为长格式后,自定义函数计算Cronbach's Alpha时出现报错:
error in rowSums(list_compl_data): 'x' is not numeric
用户代码流程:
imp.data1 <- mice(data.2, m=20, maxit=10, seed=123, predictorMatrix=pred.m, print=F) imp.data2 <- mice(data.2, m=20, maxit=10, seed=123, predictorMatrix=pred.m, print=F) imp.data <- rbind(imp.data1, imp.data2) imp.int2 <- complete(imp.data, action="long", include=F) # 自定义Cronbach's Alpha计算函数 cronbach_fun <- function(list_compl_data, boot = TRUE, B = 1e4, ci = FALSE) { n <- nrow(list_compl_data); p <- ncol(list_compl_data) total_variance <- var(rowSums(list_compl_data)) item_variance <- sum(apply(list_compl_data, 2, sd)^2) alpha <- (p/(p - 1)) * (1 - (item_variance/total_variance)) out <- list(alpha = alpha) boot_alpha <- numeric(B) if (boot) { for (i in seq_len(B)) { boot_dat <- list_compl_data[sample(seq_len(n), replace = TRUE), ] total_variance <- var(rowSums(boot_dat)) item_variance <- sum(apply(boot_dat, 2, sd)^2) boot_alpha[i] <- (p/(p - 1)) * (1 - (item_variance/total_variance)) } out$var <- var(boot_alpha) } if (ci){ out$ci <- quantile(boot_alpha, c(.025,.975)) } return(out) } # 循环计算每个插补数据集的Alpha时报错 m <- length(unique(imp.int2$.imp)) boot_alpha <- rep(list(NA), m) for (i in seq_len(m)) { set.seed(i) sub <- imp.int2[imp.int2$.imp == i, -c(1,2)] boot_alpha[[i]] <- cronbach_fun(sub) }
报错原因
传入cronbach_fun的数据集sub中存在非数值型列(比如因子、字符型变量),导致rowSums()无法执行。可能是:
- 筛选数据时误保留了非量表项目的列
- PHQ量表的部分项目未转为数值型(比如原始是因子编码)
解决步骤
1. 定位非数值型列
在循环中加入数据类型检查代码,明确哪些列导致问题:
for (i in seq_len(m)) { set.seed(i) sub <- imp.int2[imp.int2$.imp == i, -c(1,2)] # 打印数据结构,查看列类型 print(str(sub)) # 输出非数值列的位置和名称 non_num_cols <- which(!sapply(sub, is.numeric)) print("非数值型列:") print(names(sub)[non_num_cols]) boot_alpha[[i]] <- cronbach_fun(sub) }
2. 仅传入量表的数值型项目
明确指定PHQ量表的列名,确保只传入数值型题目:
# 替换为你实际的PHQ量表列名 phq_item_cols <- c("phq1", "phq2", "phq3", "phq4", "phq5", "phq6", "phq7", "phq8", "phq9") for (i in seq_len(m)) { set.seed(i) # 仅选择量表列 sub <- imp.int2[imp.int2$.imp == i, phq_item_cols] # 强制转换为数值型(处理因子/字符型编码) sub <- as.data.frame(lapply(sub, as.numeric)) boot_alpha[[i]] <- cronbach_fun(sub) }
3. 给函数增加数据验证
修改自定义函数,提前过滤非数值列并增加错误提示:
cronbach_fun <- function(list_compl_data, boot = TRUE, B = 1e4, ci = FALSE) { # 仅保留数值型列 num_cols <- sapply(list_compl_data, is.numeric) if (sum(num_cols) == 0) stop("输入数据中没有数值型列") list_compl_data <- list_compl_data[, num_cols] p <- ncol(list_compl_data) if (p < 2) stop("计算Cronbach's Alpha至少需要2个项目") n <- nrow(list_compl_data) total_variance <- var(rowSums(list_compl_data)) item_variance <- sum(apply(list_compl_data, 2, sd)^2) alpha <- (p/(p - 1)) * (1 - (item_variance/total_variance)) out <- list(alpha = alpha) boot_alpha <- numeric(B) if (boot) { for (i in seq_len(B)) { boot_dat <- list_compl_data[sample(seq_len(n), replace = TRUE), ] total_variance <- var(rowSums(boot_dat)) item_variance <- sum(apply(boot_dat, 2, sd)^2) boot_alpha[i] <- (p/(p - 1)) * (1 - (item_variance/total_variance)) } out$var <- var(boot_alpha) } if (ci){ out$ci <- quantile(boot_alpha, c(.025,.975)) } return(out) }
4. 用Rubin规则合并插补结果
计算完每个插补数据集的Alpha后,需要用Rubin规则合并得到最终结果:
# 提取所有插补数据集的Alpha值 alpha_list <- sapply(boot_alpha, function(x) x$alpha) # 计算合并后的Alpha pooled_alpha <- mean(alpha_list) # 计算总方差(插补内+插补间) within_var <- mean(sapply(boot_alpha, function(x) x$var)) between_var <- var(alpha_list) total_var <- within_var + between_var * (1 + 1/m) # 计算95%置信区间 pooled_ci <- pooled_alpha + qt(c(0.025, 0.975), df = m-1) * sqrt(total_var) # 输出结果 cat("合并后的Cronbach's Alpha:", round(pooled_alpha, 3), "\n") cat("95%置信区间:", round(pooled_ci[1], 3), "-", round(pooled_ci[2], 3), "\n")
内容的提问来源于stack exchange,提问作者mjane23
相关产品推荐
相关产品推荐

