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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 08:50:23