R语言for循环执行Shapiro-Wilk检验后如何将结果存入数据框
R 按ID分组执行Shapiro-Wilk检验并整理结果的解决方案
前提说明
- Shapiro-Wilk检验不允许输入含缺失值的向量,执行前需过滤
Values列的NA值 - 检验逻辑:原假设H0为「当前分组Values服从正态分布」,若p值<0.05则拒绝H0(接受H1,判定为非正态);若p值≥0.05则不拒绝H0(判定为正态)
方案1:基于你现有循环代码的修改版
# 加载包&准备数据 library(data.table) setDT(df) # 提前将df转为data.table,无需循环内重复操作 uniq_id <- unique(df$ID) number_loops <- length(uniq_id) headings <- c("ID", "Wilk", "p_value","结论") # 初始化结果表并设置列名 df_table <- as.data.frame(matrix(NA, nrow = number_loops, ncol = length(headings))) colnames(df_table) <- headings # 循环执行检验并填充结果 for (row_idx in 1:number_loops) { current_id <- uniq_id[row_idx] # 提取当前ID的非NA Values current_values <- df[ID == current_id, Values[!is.na(Values)]] # 执行检验 s <- shapiro.test(current_values) # 填充当前行结果 df_table$ID[row_idx] <- current_id df_table$Wilk[row_idx] <- s$statistic df_table$p_value[row_idx] <- s$p.value # 判定结论 df_table$结论[row_idx] <- ifelse(s$p.value < 0.05, "non-normal/接受H1", "normal") } # 查看最终结果 print(df_table)
方案2:更简洁的data.table原生分组实现(无需手动写循环)
library(data.table) setDT(df) df_table <- df[!is.na(Values), # 先过滤全表NA值 .(Wilk = shapiro.test(Values)$statistic, p_value = shapiro.test(Values)$p.value, 结论 = ifelse(shapiro.test(Values)$p.value < 0.05, "non-normal/接受H1", "normal")), by = ID] # 按ID分组计算
输出示例
最终得到的df_table结构如下:
| ID | Wilk | p_value | 结论 |
|---|---|---|---|
| F1 | 0.8821223 | 0.2562709 | normal |
| F2 | 0.9358824 | 0.5860217 | normal |
| F3 | 0.7403403 | 0.00549108 | non-normal/接受H1 |
| F4 | 0.9059743 | 0.3951848 | normal |
内容的提问来源于stack exchange,提问作者pipts
相关产品推荐
相关产品推荐

