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

在R中用dplyr按分组及出现顺序生成flag并聚合金额

用dplyr实现客户分组的金额聚合与标记逻辑

原始数据

customer_idstatusamountchannel
1target15shop
1beneficiary10shop
1beneficiary5shop
2target25shop
3beneficiary30online
3beneficiary15shop
3target10shop

需求说明

  1. 生成flag字段:按customer_id分组,找到每组内第一条status为"beneficiary"的记录:
    • 若该记录的channel为"shop",标记flag为"taker"
    • 若该记录的channel非"shop",或组内无"beneficiary"记录,标记flag为"targeted"
  2. 生成ttl_amount字段:按customer_id分组计算总金额

预期结果

customer_idttl_amountflag
130taker
225targeted
355targeted

注:原预期结果中customer_id=1的flag标注为"beneficiary"应为笔误,按需求规则正确标记应为"taker"

dplyr实现代码

library(dplyr)

# 假设原始数据框名为df
df %>%
  group_by(customer_id) %>%
  mutate(
    # 计算客户总金额
    ttl_amount = sum(amount),
    # 获取第一条beneficiary记录的channel,无匹配则返回NA
    first_benefit_channel = channel[match("beneficiary", status)],
    # 根据规则生成flag
    flag = case_when(
      !is.na(first_benefit_channel) & first_benefit_channel == "shop" ~ "taker",
      TRUE ~ "targeted"
    )
  ) %>%
  # 去重保留每个客户的唯一聚合记录
  distinct(customer_id, ttl_amount, flag) %>%
  ungroup()

代码逻辑解释

  • group_by(customer_id):按客户ID分组处理
  • sum(amount):直接计算每组的交易总金额
  • channel[match("beneficiary", status)]:match()返回status列中首次出现"beneficiary"的索引位置,用该索引提取对应channel值;若组内无"beneficiary",则返回NA
  • case_when():多条件判断生成flag:仅当存在第一条beneficiary且对应channel为shop时标记"taker",其余所有情况统一标记"targeted"
  • distinct():分组后每条记录都带有相同的聚合结果,去重后保留每个客户的唯一记录
  • ungroup():取消分组,恢复为普通数据框结构

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 18:15:35