在R中用dplyr按分组及出现顺序生成flag并聚合金额
用dplyr实现客户分组的金额聚合与标记逻辑
原始数据
| customer_id | status | amount | channel |
|---|---|---|---|
| 1 | target | 15 | shop |
| 1 | beneficiary | 10 | shop |
| 1 | beneficiary | 5 | shop |
| 2 | target | 25 | shop |
| 3 | beneficiary | 30 | online |
| 3 | beneficiary | 15 | shop |
| 3 | target | 10 | shop |
需求说明
- 生成
flag字段:按customer_id分组,找到每组内第一条status为"beneficiary"的记录:- 若该记录的
channel为"shop",标记flag为"taker" - 若该记录的
channel非"shop",或组内无"beneficiary"记录,标记flag为"targeted"
- 若该记录的
- 生成
ttl_amount字段:按customer_id分组计算总金额
预期结果
| customer_id | ttl_amount | flag |
|---|---|---|
| 1 | 30 | taker |
| 2 | 25 | targeted |
| 3 | 55 | targeted |
注:原预期结果中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",则返回NAcase_when():多条件判断生成flag:仅当存在第一条beneficiary且对应channel为shop时标记"taker",其余所有情况统一标记"targeted"distinct():分组后每条记录都带有相同的聚合结果,去重后保留每个客户的唯一记录ungroup():取消分组,恢复为普通数据框结构
内容的提问来源于stack exchange,提问作者GitZine
相关产品推荐
相关产品推荐

