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

在R的dplyr中实现按组条件累积求和

按组实现条件累积求和需求

需求说明:为数据框df按组添加一列条件累积求和列exp_output,规则如下:

  • 当margin列的值为负数时,正常累加该值
  • 当margin列的值为正数时,用当前累积值减去该正数(等价于累加该正数的相反数)

原数据框

df <- data.frame(
  group = c('g1', 'g1', 'g1', 'g1', 'g1', 'g2', 'g2', 'g2', 'g2', 'g2', 'g2', 'g2', 'g2'),
  margin = c(-1.72, -1.13, -0.64, 1.75, 1.75, -7.22, -1.99, -1.13, -0.15, 1.31, 1.37, 1.98, 5.84) )

期望输出

df <- data.frame(
  group = c('g1', 'g1', 'g1', 'g1', 'g1', 'g2', 'g2', 'g2', 'g2', 'g2', 'g2', 'g2', 'g2'),
  margin = c(-1.72, -1.13, -0.64, 1.75, 1.75, -7.22, -1.99, -1.13, -0.15, 1.31, 1.37, 1.98, 5.84),
  exp_output = c(-1.72, -2.86, -3.50, -5.25, -7.00, -7.22, -9.22, -10.36, -10.51, -11.82, -13.20, -15.19, -21.03) )

解决方案

核心思路是先根据margin的正负调整数值符号:正数取相反数,负数保持不变,再对调整后的数值按组做累积求和,即可实现需求中的条件累加逻辑。

简洁实现代码

library(dplyr)

df <- df %>%
  group_by(group) %>%
  mutate(exp_output = cumsum(ifelse(margin > 0, -margin, margin))) %>%
  ungroup() # 可选:取消分组,避免后续操作受分组状态影响

分步解释(便于理解)

如果需要更清晰的步骤,可以拆分出中间调整列:

df <- df %>%
  group_by(group) %>%
  mutate(
    # 调整数值符号:正数转负,负数保留
    adjusted_margin = case_when(
      margin > 0 ~ -margin,
      TRUE ~ margin
    ),
    # 对调整后的值做累积求和
    exp_output = cumsum(adjusted_margin)
  ) %>%
  select(-adjusted_margin) # 移除中间辅助列
  ungroup()

验证结果:运行上述代码后,exp_output列将完全匹配期望输出。比如g1组第四行,原margin=1.75被转为-1.75,累加到前一行的-3.50后得到-5.25,完全符合需求逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 21:17:47