使用rstatix进行混合ANOVA:NA处理后自由度异常偏低问题
关于rstatix::anova_test()混合ANOVA缺失数据的调试解决方法
问题背景
使用rstatix包的anova_test()做两因素混合ANOVA分析:1个组间因子(2组)、1个组内因子(2个时间点),数据集为长格式。运行时收到警告:Warning message: NA detected in rows: 49. Removing this rows before the analysis.,但输出中组内效应的分母自由度(DFd)为17,按公式DFd=(N−k)×(m−1)反推,模型仅纳入19名被试——但手动核查应有25个完整案例,疑似额外静默删除了5名被试。
问题1:为何仅警告第49行,实际却删了更多被试?
anova_test()默认采用按被试删除不完整案例(listwise deletion):只要某个被试的任意一个时间点数据存在NA,该被试的所有行都会被整体移除。但警告机制只会提示第一个检测到的NA所在行,不会逐个列出所有包含NA的行。比如第49行是某被试的一个时间点有NA,这个被试会被完全删除;另外5个被试的NA可能出现在其他行,但因为警告只触发第一次NA检测,所以你只看到第49行的提示。
问题2:如何查看被删除的具体行/被试?
直接用以下代码手动排查:
- 先定位所有含NA的被试(假设数据框为
df,被试ID列是subject_id,因变量列是dv):# 筛选出存在缺失值的被试 na_subjects <- df %>% group_by(subject_id) %>% summarise(has_na = any(is.na(dv))) %>% filter(has_na) # 查看这些被试的全部数据行 df %>% filter(subject_id %in% na_subjects$subject_id) - 提取ANOVA内部使用的清理后数据,对比找出被排除的被试:
# 先运行ANOVA并保存结果 anova_result <- anova_test(data = df, dv = dv, wid = subject_id, between = group, within = time) # 提取分析用的清理后数据集 cleaned_data <- get_test_data(anova_result) # 找出原数据中未被纳入分析的被试 excluded_subjects <- setdiff(unique(df$subject_id), unique(cleaned_data$subject_id)) # 查看这些被试的详细数据 df %>% filter(subject_id %in% excluded_subjects)
额外调试建议
- 检查隐性缺失:用
summary(df)查看各列统计量,确认是否存在空字符串、极端值(如999)这类被误编码的缺失情况; - 验证自由度:计算清理后数据的被试数量
n_distinct(cleaned_data$subject_id),代入公式DFd=(N−k)×(m−1)(N=被试数,k=组间组数,m=组内时间点数量),确认是否与输出的DFd一致。
内容的提问来源于stack exchange,提问作者Carolina Schäfer
相关产品推荐
相关产品推荐

