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

基于双条件筛选ID:保留180天内购买不同车型的用户数据

问题描述

我创建了如下示例dataframe:

df <- data.frame(id = c(1,1,1,2,2,2,2,3,3), 
                 car = c("subaru", "audi", "subaru", "toyota", "toyota", "audi", "subaru", "nissan", "nissan"),
                buy_date = c("01/01/2000", "01/01/2001", "01/02/2001", "01/01/2000", "01/05/2000", "01/01/2005", "01/03/2005", "01/01/2000", "02/01/2000"))

df$buy_date <- as.Date(df$buy_date, format="%d/%m/%Y") #此转换目前存在问题,但暂不关注

生成的数据框:

idcarbuy_date
1subaru2000-01-01
1audi2001-01-01
1subaru2001-02-01
2toyota2000-01-01
2toyota2004-12-01
2audi2005-01-01
2subaru2005-03-01
3nissan2000-01-01
3nissan2000-01-02

需求:针对每个ID,若该用户在180天内购买过两种不同类型的车型,则保留该ID对应的相关行。期望结果:

idcarbuy_date
1audi2001-01-01
1subaru2001-02-01
2toyota2004-12-01
2audi2005-01-01
2subaru2005-03-01
解决方案

方法1:使用dplyr的前后行比较

仅依赖dplyr包即可实现,逻辑简洁直接:

library(dplyr)

result <- df %>%
  group_by(id) %>%
  arrange(buy_date) %>%
  # 标记当前行是否属于符合条件的记录组
  mutate(
    # 检查当前行之后180天内是否存在不同车型
    qualify = any((lead(buy_date, default = last(buy_date)+181) <= buy_date + 180) & (car != lead(car, default = car))),
    # 补充检查当前行之前180天内是否存在不同车型
    qualify = qualify | any((lag(buy_date, default = first(buy_date)-181) >= buy_date - 180) & (car != lag(car, default = car)))
  ) %>%
  filter(qualify) %>%
  select(-qualify) %>%
  ungroup()

print(result)

方法2:使用slider包的滑动窗口(更灵活)

如果需要更精准的时间范围判断,推荐使用slider包的滑动窗口功能,适配复杂场景:

library(dplyr)
library(slider)

result <- df %>%
  group_by(id) %>%
  arrange(buy_date) %>%
  # 检查当前日期前后180天窗口内是否存在不同车型
  mutate(has_diff_car = slide_lgl(
    .x = car,
    .i = buy_date,
    .f = ~ length(unique(.x)) > 1,
    .before = 180,
    .after = 180
  )) %>%
  filter(has_diff_car) %>%
  select(-has_diff_car) %>%
  ungroup()

print(result)

两种方法均能得到期望结果,方法1适合基础场景,方法2更适配复杂时间窗口的判断需求。

内容的提问来源于stack exchange,提问作者Badboybørge

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 19:07:01