使用purrr::map实现多时点t.test检验及患者测量值差值计算
实现方案
我们可以结合tidyverse的purrr、dplyr、tidyr以及broom包来完成你的两个需求,完整代码如下:
1. 前置准备:加载包与数据预处理
# 加载所需包 library(tidyverse) library(broom) # 用于标准化整理统计检验结果 # 修正原始数据定义(原写法用<-会额外生成全局变量,改为=更规范) df1 <- data.frame( pacient = c(6430, 6430, 6430, 6494, 6494, 6494, 6165, 6165, 6165), time = c(00, 01, 66, 00, 01, 66, 00, 01, 66), weight = c(115, 112, 110, 98, 95, 94, 88, 87, 86), waist = c(123, NA, 112, 115, 112, 113, 112, 110, NA), p14_total = c(7, NA, 4, 12, 5, NA, 15, 12, 13) ) # 为time添加明确标签,避免后续混淆 df1$time <- factor(df1$time, levels = c("00", "66", "01"), labels = c("基线", "6个月随访", "12个月随访"))
2. 需求1:多指标多时间点非配对t检验
# 生成所有需要比较的时间点两两组合 time_comps <- combn(levels(df1$time), 2, simplify = FALSE) # 批量执行t检验并整理为结构化数据框 t_test_res <- map_dfr(c("weight", "waist", "p14_total"), function(metric) { map_dfr(time_comps, function(comp_pair) { # 提取两组对应指标的数值 g1_val <- df1[[metric]][df1$time == comp_pair[1]] g2_val <- df1[[metric]][df1$time == comp_pair[2]] # 执行非配对t检验,默认采用Welch校正不假设方差齐,需方差齐可加参数var.equal = TRUE t_result <- t.test(g1_val, g2_val, na.rm = TRUE) # 整理为表格格式 tidy(t_result) %>% mutate( 测量指标 = metric, 对比组 = paste(comp_pair[1], "vs", comp_pair[2]), 组1均值 = mean(g1_val, na.rm = TRUE), 组2均值 = mean(g2_val, na.rm = TRUE) ) %>% select(测量指标, 对比组, 组1均值, 组2均值, t值 = statistic, p值 = p.value, 置信区间下限 = conf.low, 置信区间上限 = conf.high) }) })
运行后得到的t_test_res就是包含所有统计量的结构化数据框,缺失值会自动在计算时忽略。
3. 需求2:生成患者个体的指标差值列
# 先将长表转为宽表,每个时间点的指标单独为一列 df_wide <- df1 %>% pivot_wider( id_cols = pacient, names_from = time, values_from = c(weight, waist, p14_total), names_glue = "{.value}_{time}" ) # 按要求计算各指标的时间差值 df_with_diff <- df_wide %>% mutate( # 6个月差值=12个月随访值 - 6个月随访值 weight_6months_diff = weight_12个月随访 - weight_6个月随访, # 12个月差值=12个月随访值 - 基线值 weight_12months_diff = weight_12个月随访 - weight_基线, waist_6months_diff = waist_12个月随访 - waist_6个月随访, waist_12months_diff = waist_12个月随访 - waist_基线, p14_total_6months_diff = p14_total_12个月随访 - p14_total_6个月随访, p14_total_12months_diff = p14_total_12个月随访 - p14_total_基线 )
运行后得到的df_with_diff就是每例患者对应所有差值的数据集,不需要保留原始各时间点值的话可以用select()删除对应列。
内容的提问来源于stack exchange,提问作者Javier Hernando
相关产品推荐
相关产品推荐

