如何在R中批量执行受试者与基线的Mann-Whitney检验
解决方案:针对受试者与基线组的Mann-Whitney检验批量实现
1. 模拟示例数据
先构造一个与你描述结构一致的示例数据框,方便测试代码:
set.seed(123) DF <- data.frame( Subject = rep(c("Patient1", "Patient1(B)", "Patient2", "Patient2(B)", "Patient3", "Patient3(B)"), each = 5), Avg_Score = rnorm(30, mean = 70, sd = 10), EOTM = rnorm(30, mean = 50, sd = 8), FSO_1 = rnorm(30, mean = 60, sd = 12) )
2. 基础循环实现(逻辑直观)
这种方法适合快速理解核心逻辑,在中等规模数据集上表现稳定:
# 提取所有非基线受试者ID(去除(B)标记) subject_ids <- unique(gsub("\\(B\\)", "", DF$Subject)) subject_ids <- subject_ids[subject_ids != ""] # 初始化存储结果的列表 p_results <- list() # 循环处理每个受试者 for (id in subject_ids) { # 提取当前受试者的非基线数据 non_baseline <- DF[DF$Subject == id, c("Avg_Score", "EOTM", "FSO_1")] # 提取对应基线组的数据 baseline <- DF[DF$Subject == paste0(id, "(B)"), c("Avg_Score", "EOTM", "FSO_1")] # 对三个指标分别执行Mann-Whitney检验,提取p值 p_avg <- wilcox.test(non_baseline$Avg_Score, baseline$Avg_Score)$p.value p_eotm <- wilcox.test(non_baseline$EOTM, baseline$EOTM)$p.value p_fso1 <- wilcox.test(non_baseline$FSO_1, baseline$FSO_1)$p.value # 将结果存入列表 p_results[[id]] <- data.frame( Subject = id, Avg_Score_p = p_avg, EOTM_p = p_eotm, FSO_1_p = p_fso1 ) } # 合并列表为最终结果数据框DF2 DF2 <- do.call(rbind, p_results)
3. 大数据集优化实现(dplyr+purrr)
如果数据集规模较大(如上万个受试者),推荐使用向量化分组处理,效率比显式循环更高:
library(dplyr) library(purrr) # 预处理数据:添加分组ID和基线标记 DF_processed <- DF %>% mutate( Group_ID = gsub("\\(B\\)", "", Subject), Is_Baseline = grepl("\\(B\\)", Subject) ) # 分组执行检验并生成结果 DF2 <- DF_processed %>% group_by(Group_ID) %>% do({ # 分离当前组的基线和非基线数据 baseline_data <- .[.$Is_Baseline == TRUE, c("Avg_Score", "EOTM", "FSO_1")] non_baseline_data <- .[.$Is_Baseline == FALSE, c("Avg_Score", "EOTM", "FSO_1")] # 批量计算三个指标的p值 p_vals <- map_dfr(c("Avg_Score", "EOTM", "FSO_1"), function(col) { test_result <- wilcox.test(non_baseline_data[[col]], baseline_data[[col]]) tibble(!!paste0(col, "_p") := test_result$p.value) }) # 组合受试者ID和p值结果 tibble(Subject = first(.$Group_ID)) %>% bind_cols(p_vals) }) %>% ungroup() %>% select(-Group_ID)
注意事项
- 若数据存在缺失值,可在
wilcox.test中添加na.rm = TRUE参数忽略缺失值 - 默认是双侧检验,如需单侧检验可添加
alternative = "less"或alternative = "greater"参数
内容的提问来源于stack exchange,提问作者dkcongo
相关产品推荐
相关产品推荐

