You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用dplyr按条件批量汇总多变量:正态/非正态分布统计量计算

批量按正态分布类型汇总数据(mtcars示例)

方法一:使用dplyr的across批量处理

这种方式贴合tidyverse风格,代码简洁高效:

library(dplyr)

# 手动指定正态变量(可根据实际检验结果调整)
norm_vars <- c("qsec", "drat", "hp", "mpg")
# 自动生成非正态变量(排除分组变量am)
non_norm_vars <- setdiff(names(mtcars), c("am", norm_vars))

# 分组批量汇总
summary_df <- mtcars %>%
  group_by(am) %>%
  summarise(
    # 正态变量:输出 mean (sd),保留两位小数
    across(all_of(norm_vars), 
           ~paste0(round(mean(.x, na.rm = TRUE), 2), 
                   " (", round(sd(.x, na.rm = TRUE), 2), ")"),
           .names = "{.col}_mean_sd"),
    # 非正态变量:输出 median (Q1-Q3),保留两位小数
    across(all_of(non_norm_vars), 
           ~{
             qs <- quantile(.x, na.rm = TRUE)
             paste0(round(median(.x, na.rm = TRUE), 2), 
                    " (", round(qs[2], 2), "-", round(qs[4], 2), ")")
           },
           .names = "{.col}_median_iqr")
  )

# 查看结果
print(summary_df)

自动判断正态性(可选)

如果不想手动指定变量,可通过 Shapiro-Wilk 检验自动筛选(注意:该检验适合小样本,大样本易因微小偏差拒绝原假设):

library(purrr)

# 批量执行正态性检验
norm_test_results <- mtcars %>%
  select(-am) %>%
  map_df(~tibble(p_value = shapiro.test(.x)$p.value), .id = "variable")

# 以p>0.05为标准划分变量
auto_norm_vars <- norm_test_results %>% filter(p_value > 0.05) %>% pull(variable)
auto_non_norm_vars <- norm_test_results %>% filter(p_value <= 0.05) %>% pull(variable)

# 将上述汇总代码中的norm_vars/non_norm_vars替换为自动生成的变量即可

方法二:for循环结合rbind处理

若习惯循环逻辑,可采用以下方案:

# 初始化空结果数据框
summary_loop <- data.frame()

# 遍历am的每个分组值
for (group_val in unique(mtcars$am)) {
  # 提取当前分组的数据
  group_data <- mtcars[mtcars$am == group_val, ]
  
  # 计算正态变量的mean±sd
  norm_stats <- sapply(norm_vars, function(var) {
    val <- group_data[[var]]
    paste0(round(mean(val, na.rm = TRUE), 2), " (", round(sd(val, na.rm = TRUE), 2), ")")
  })
  
  # 计算非正态变量的中位数及四分位数
  non_norm_stats <- sapply(non_norm_vars, function(var) {
    val <- group_data[[var]]
    qs <- quantile(val, na.rm = TRUE)
    paste0(round(median(val, na.rm = TRUE), 2), " (", round(qs[2], 2), "-", round(qs[4], 2), ")")
  })
  
  # 合并当前分组结果并绑定到总数据框
  current_row <- data.frame(am = group_val, t(c(norm_stats, non_norm_stats)))
  summary_loop <- rbind(summary_loop, current_row)
}

# 设置清晰的列名
colnames(summary_loop) <- c("am", paste0(norm_vars, "_mean_sd"), paste0(non_norm_vars, "_median_iqr"))

# 查看结果
print(summary_loop)

内容的提问来源于stack exchange,提问作者Mark Davies

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 19:37:59