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

基于dplyr&purrr实现分组多列复杂条件汇总的优雅方案问询

用dplyr + purrr优雅实现分组条件汇总

嘿,我来帮你搞定这个分组汇总的需求!你的思路方向是对的,但原来的代码有几个小问题,比如语法格式不对,还没覆盖第三个条件。咱们用更现代的dplyr语法结合purrr的批量处理能力,就能写出既简洁又易维护的代码。

先明确需求拆解

我们需要按id分组后,对d_amt、d_cnt、w_amt、w_cnt这4个数值列,分别计算三类统计值:

  • 全量数据的求和
  • 仅当diff < 11时的条件求和
  • 仅当diff < 21时的条件求和

问题代码的小坑

你原来的summarise_if写法有两处问题:

  1. .funs参数需要是命名列表或者单个函数,你写的(sum,~sum(.[diff<11]))格式不符合要求
  2. summarise_if已经被dplyr的across替代,across更灵活,能更好地结合purrr做批量操作

优雅解决方案

我们用dplyr::across搭配purrr风格的函数列表来实现,代码清晰且易于扩展:

首先加载需要的包:

library(dplyr)
library(purrr)

然后直接处理数据:

# 先定义要执行的三类求和操作,用列表存储更易维护
sum_ops <- list(
  total = ~sum(., na.rm = TRUE),          # 全量求和
  diff_lt11 = ~sum(.[diff < 11], na.rm = TRUE),  # diff<11条件求和
  diff_lt21 = ~sum(.[diff < 21], na.rm = TRUE)   # diff<21条件求和
)

# 分组汇总
result <- df %>%
  group_by(id) %>%
  summarise(
    # 选择目标数值列:排除id和diff,只保留需要汇总的4列
    across(
      .cols = where(is.numeric) & !c(id, diff),
      .fns = sum_ops,
      .names = "{.col}_{.fn}"  # 自动生成清晰的列名,比如d_amt_total
    )
  )

# 查看结果
result

代码解释

  1. sum_ops列表:把三类求和操作封装成命名列表,以后要加新的条件(比如diff<30),直接在列表里加一行就行,非常灵活
  2. across函数:
    • .cols参数精准筛选需要处理的列:where(is.numeric)选数值列,再排除id和diff
    • .fns传入我们定义的操作列表,自动对每个选中的列执行所有操作
    • .names参数控制输出列的命名规则,让结果列名一目了然(比如d_amt_diff_lt11就表示d_amt列中diff<11的求和)
  3. na.rm=TRUE:避免因为某个分组里没有符合条件的行(比如没有diff<11的记录)导致结果为NA,会自动返回0,更符合业务需求

验证示例结果

比如看id=10274557的分组:

  • 该组里只有1行diff=8(满足diff<11),对应的d_amt是98,所以d_amt_diff_lt11的结果就是98,和预期一致
  • 满足diff<21的行有2行(diff=8和diff=17),对应的d_amt是98+30=128,所以d_amt_diff_lt21的结果是128,完全正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 22:52:28