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

如何使用dplyr按分组计算数据框所有数值列的分位数

问题原因

代码无法运行核心是两个问题:

  • across()语法使用错误:across()第一个参数传列筛选规则,第二个参数传要应用的计算逻辑,你把where(is.numeric)列筛选逻辑和计算公式混写在第二个参数位,无法被正确识别。
  • 原自定义函数quibble返回的分位值列固定命名为x,和原数据的x列重名,多列计算时会触发列名冲突;且多列返回的嵌套结果直接unnest会因为结构不统一报错。
正确实现方法

方法1:先转长格式再计算(逻辑最简洁,推荐)

不需要嵌套结果再解套,先把所有数值列转换为长格式,按「分组+原列名」双维度分组后直接计算分位数即可,自动过滤非数值列、自动处理缺失值:

library(tidyverse)

# 原测试数据构造
df <- tibble(
  grp = rep(c("A","B"), each = 5), 
  x = c(rnorm(5, -0.25, 1), rnorm(5, 0, 1.5)),
  y = c(rnorm(5, 0.25, 1), rnorm(5, 0, 0.5)),
  z = letters[1:10],
)
df[3,2] <- NA

# 调整自定义函数,避免列名冲突
quibble <- function(x, q = c(0.25, 0.5, 0.75), dropNA = TRUE) {
  tibble(value = quantile(x, q, na.rm = dropNA), q = q)
}

# 计算代码
df %>% 
  pivot_longer(cols = where(is.numeric), names_to = "col_name", values_to = "calc_val") %>% 
  group_by(grp, col_name) %>% 
  summarise(quibble(calc_val, q = c(0.25, 0.75), dropNA = TRUE), .groups = "drop")

运行后输出结果结构如下(随机数生成数值不同,分位值会有差异):

# A tibble: 8 × 4
  grp   col_name   value     q
  <chr> <chr>      <dbl> <dbl>
1 A     x         -0.353  0.25
2 A     x          0.484  0.75
3 A     y         -0.419  0.25
4 A     y          1.15   0.75
5 B     x         -1.27   0.25
6 B     x          1.05   0.75
7 B     y         -0.168  0.25
8 B     y          0.252  0.75

方法2:保留across写法,嵌套计算后解套

如果要保留across逐列计算的逻辑,需要把每列的计算结果存为嵌套列表,转成长格式后再统一展开:

df %>% 
  group_by(grp) %>%
  summarise(
    across(where(is.numeric), ~list(quibble(.x, c(0.25, 0.75), dropNA = TRUE)))
  ) %>% 
  pivot_longer(cols = -grp, names_to = "col_name", values_to = "res") %>% 
  unnest(res)

输出结果和方法1完全一致。

注意:不需要额外加载其他包,所有函数都是tidyverse内置,非数值列z会被自动排除,缺失值会按照na.rm=TRUE的设置忽略后计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:09:26