如何用dplyr基于另一表的条件筛选符合资格的客户ID?
用dplyr实现促销期内购买客户的筛选/标记
当然可以用dplyr轻松搞定,完全不用写遍历循环的代码,下面给你两种实用的实现思路,先拿示例数据演示:
示例数据
先构造两个测试表:
library(dplyr) # 表1:客户促销信息 promotions <- tibble( customer_id = c(1, 2, 3), promo_start = as.Date(c("2023-01-01", "2023-02-01", "2023-03-01")), promo_end = as.Date(c("2023-01-10", "2023-02-10", "2023-03-10")) ) # 表2:客户购买记录 purchases <- tibble( customer_id = c(1, 2, 3), purchase_date = as.Date(c("2023-01-05", "2023-01-15", "2023-03-15")) )
思路一:标记所有客户是否为受益人
如果需要在原促销表基础上,给每个客户添加「是否在促销期内购买」的标记,用以下代码:
promotions_with_benefit <- promotions %>% left_join(purchases, by = "customer_id") %>% group_by(customer_id, promo_start, promo_end) %>% mutate(is_beneficiary = any(purchase_date >= promo_start & purchase_date <= promo_end, na.rm = TRUE)) %>% ungroup() %>% distinct(customer_id, .keep_all = TRUE) print(promotions_with_benefit)
- 先用
left_join把两个表按客户ID关联,确保每个促销记录都能匹配到对应的购买记录 - 按客户ID和促销信息分组,用
any()判断该客户是否存在符合条件的购买日期(na.rm=TRUE是处理那些没有购买记录的客户) - 最后去重,保留每个客户的唯一记录
思路二:直接筛选出符合条件的客户
如果只需要从促销表里提取出确实在促销期内有购买的客户,用semi_join更高效:
qualified_customers <- promotions %>% semi_join(purchases, by = "customer_id") %>% filter( exists( ~ any(purchase_date >= promo_start & purchase_date <= promo_end), data = purchases %>% filter(customer_id == !!cur_data()$customer_id) ) ) print(qualified_customers)
semi_join先过滤掉那些完全没有购买记录的客户- 再用
filter结合exists(),检查每个客户的购买记录中是否存在处于其促销区间内的日期
两种方法都能替代你之前的遍历思路,而且更符合tidyverse的风格,代码简洁还易维护。
内容的提问来源于stack exchange,提问作者GitZine
相关产品推荐
相关产品推荐

