You need to enable JavaScript to run this app. 如何使用dplyr生成统计量为行、变量为列的多变量汇总表
优惠活动
大模型
产品
解决方案
定价
更多

如何使用dplyr生成统计量为行、变量为列的多变量汇总表

问题解答

更优雅的实现方案

你可以通过across传入函数列表+长宽转换的方式实现相同效果,只需扫描一次数据集,代码扩展性更强:

library(tidyverse)

starwars %>% 
  # 一次计算所有统计量,生成「列名_统计名」格式的宽列
  summarise(across(where(is.numeric), 
                   list(min = min, median = median, mean = mean, max = max, sd = sd),
                   na.rm = TRUE)) %>% 
  # 转为长表,拆分列名得到变量名和统计名
  pivot_longer(everything(), 
               names_to = c("variable", "statistic"), 
               names_sep = "_") %>% 
  # 再转回你需要的宽表结构
  pivot_wider(names_from = variable, values_from = value) %>% 
  # 可选:调整统计量顺序和你原输出一致
  arrange(factor(statistic, levels = c("min", "median", "mean", "max", "sd")))

运行结果和你用bind_rows得到的完全一致。

为什么无法直接通过summarize实现目标结构

summarize的设计逻辑是无分组时输入任意行、输出1行汇总结果,有分组时输出和分组数相等的行数,每一个汇总表达式对应输出一列。
当你给across传入多个函数时,默认会生成原变量名_函数名格式的多列结果,是面向宽表汇总的默认设计,并不会自动把统计量名称转换为行维度,因此需要搭配tidyr的转换函数调整结构,并不是无法实现该需求。

关于整洁数据原则的疑问

  • 你想要的「统计量为行、数值变量为列」的输出属于面向人阅读的宽整洁结构,本身没有违反整洁数据原则:每一行对应一个统计类别,每一列对应一个观测指标,每个单元格只有一个值,符合整洁数据的核心要求。
  • 你原来用bind_rows拼接的实现方式,结果是合规的,但存在两个明显的问题:
    • 代码冗余:重复调用5次summarize(across(...)),如果要新增/删除统计量、修改筛选列的规则,需要同步修改多处,容易出错
    • 执行效率低:需要对数据集扫描5次才能完成所有统计量计算,优化方案只需要扫描1次
  • 官方文档推荐的传入函数列表方案,看起来多了两步转换,但扩展性、可维护性都远高于拼接方案,熟悉tidyverse语法后写起来也更快捷。

内容的提问来源于stack exchange,提问作者Lucas De Abreu Maia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 03:54:03