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

如何在R中基于Cust_ID和3天内日期生成唯一ID列

在R中为同一客户3天内的申请生成唯一ID

问题背景

我有如下数据框:

dataframe <- data.frame(Cust_ID = c("1","2","2","3","1","3"), 
                        App_date = as.Date(c("2023-05-01","2023-05-02","2023-05-03","2023-05-06","2023-04-28","2023-04-04")),
                        Product = c("AA","AA","BB","AA","CC","BB"))

希望新增一列Unique_id,规则是:同一Cust_ID下,App_date处于3天时间范围内的行共享相同的唯一ID。期望得到的结果如下:

result <- data.frame(Cust_ID = c("1","2","2","3","1","3"), 
                        App_date = as.Date(c("2023-05-01","2023-05-02","2023-05-03","2023-05-06","2023-04-28","2023-04-04")),
                        Product = c("AA","AA","BB","AA","CC","BB"),
                        Unique_id = c("A1","A2","A2","A3","A1","A4"))

请问如何在R中实现这个需求?

解决方案

方法1:使用dplyr + lubridate

核心逻辑是按客户分组后,通过日期间隔划分连续的时间块,再给每个时间块分配全局唯一ID:

library(dplyr)
library(lubridate)

dataframe %>%
  arrange(Cust_ID, App_date) %>%
  group_by(Cust_ID) %>%
  # 标记新时间块的起点:首行或与上一行日期差超过3天的行
  mutate(break_point = ifelse(row_number() == 1, TRUE, App_date - lag(App_date) > 3)) %>%
  # 累计求和生成组内时间块编号
  mutate(block = cumsum(break_point)) %>%
  ungroup() %>%
  # 将客户+组内块的组合转换为全局唯一的A开头ID
  mutate(Unique_id = paste0("A", dense_rank(paste(Cust_ID, block))))

方法2:使用data.table(适合大数据集)

用data.table的语法实现相同逻辑,处理大规模数据时效率更高:

library(data.table)

setDT(dataframe)[order(Cust_ID, App_date), 
                 block := cumsum(c(TRUE, diff(App_date) > 3)), 
                 by = Cust_ID][, 
                               Unique_id := paste0("A", dense_rank(paste(Cust_ID, block)))]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 17:57:48