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

如何在dplyr分组聚合时对含B的列取分位数,其余列取均值?

解决方案

你可以通过两种方式实现需求,无需创建额外的dataframe,直接在原dplyr管道中完成:

方法一:单across内按列名判断逻辑

利用cur_column()获取当前处理的列名,在across的函数中通过条件判断选择计算方式:

library(dplyr)    

df <- data.frame(mydate=as.Date(c("2000-01-15", "2000-02-15", "2000-03-15")), columnA=c(2, 4, 5), columnB=c(3, 6, 7))

df %>%
  mutate(year = format(mydate, "%Y")) %>%
  group_by(year) %>%
  summarise(
    across(
      where(is.numeric),
      ~ if_else(grepl("B", cur_column(), fixed = TRUE),
                quantile(.x, probs = 0.9, na.rm = TRUE),
                mean(.x, na.rm = TRUE))
    ),
    .groups = "drop" # 可选,聚合后取消分组状态
  )
  • cur_column()是dplyr内置函数,用于在across内部获取当前列的名称
  • if_else根据列名是否包含"B",分别执行分位数计算或均值计算
  • .groups = "drop"可以避免后续操作受分组状态影响,按需添加

方法二:拆分across分别处理列

这种方式可读性更强,通过matches("B")匹配列名,拆分两个across分别处理不同列:

df %>%
  mutate(year = format(mydate, "%Y")) %>%
  group_by(year) %>%
  summarise(
    # 处理列名含"B"的数值列
    across(
      where(is.numeric) & matches("B"),
      ~ quantile(.x, probs = 0.9, na.rm = TRUE)
    ),
    # 处理其余数值列
    across(
      where(is.numeric) & !matches("B"),
      ~ mean(.x, na.rm = TRUE)
    ),
    .groups = "drop"
  )
  • matches("B")用于匹配列名包含"B"的列,结合where(is.numeric)筛选出目标数值列
  • 两个across分别执行不同的聚合逻辑,结果会自动合并到同一结果集中

说明

你之前的错误在于试图用ifelse包裹整个summarise操作,这不符合dplyr的管道逻辑。正确的做法是将条件判断放在across内部的列级处理逻辑中,或是拆分across分别处理不同列组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 03:57:49