如何在R语言中识别指定日期窗口内出现次数>1的ID
实现R函数:识别时间窗口内重复出现的ID
需要编写一个R函数,判断指定ID是否在n天的时间窗口内出现超过1次:
- 当
n=1时,识别单日出现多次的ID - 当
n=2时,识别连续两天周期内(如昨日与今日、今日与明日)出现多次的ID
示例数据与期望输出
先定义测试数据:
data <- data.frame(date = c(1,1,1,2,2,2,3,3,3), id = c(1,1,2,1,3,4,1,2,5)) data # date id # 1 1 1 # 2 1 1 # 3 1 2 # 4 2 1 # 5 2 3 # 6 2 4 # 7 3 1 # 8 3 2 # 9 3 5
函数需要返回1(该ID在n天窗口内出现超过1次)或0(否则),并添加为数据框的dupe列。
当n=1时的期望结果:
data$dupe <- dupe_detect(data, date, id, n = 1) data # date id dupe # 1 1 1 1 # 2 1 1 1 # 3 1 2 0 # 4 2 1 0 # 5 2 3 0 # 6 2 4 0 # 7 3 1 0 # 8 3 2 0 # 9 3 5 0
当n=2时的期望结果:
data$dupe <- dupe_detect(data, date, id, n = 2) data # date id dupe # 1 1 1 1 # 2 1 1 1 # 3 1 2 1 # 4 2 1 1 # 5 2 3 0 # 6 2 4 0 # 7 3 1 1 # 8 3 2 1 # 9 3 5 0
函数实现方案
基于dplyr的分组与窗口函数实现,核心逻辑是对每个ID的日期序列,检查是否存在符合时间窗口的重复记录:
library(dplyr) dupe_detect <- function(data, date_col, id_col, n){ # 转换列名为符号,支持非标准参数传入 date_sym <- enquo(date_col) id_sym <- enquo(id_col) data %>% group_by(!!id_sym) %>% mutate( # 计算当前行与同ID其他行的日期差绝对值 within_window = any(abs(!!date_sym - !!date_sym) <= n & row_number() != row_number()), # 判断是否满足重复条件:窗口内有重复,或同一日期多次出现 has_dupe = (within_window | any(duplicated(!!date_sym))) & n() > 1 ) %>% ungroup() %>% pull(has_dupe) %>% as.integer() }
逻辑说明
- 分组处理:按ID分组,仅针对同一ID的日期记录做判断
- 窗口检查:对每个ID的所有日期,判断是否存在与当前行日期差≤n天的其他记录
- 重复判定:
- 若同一ID在时间窗口内出现多次,或同一日期内出现多次,标记为1
- 仅出现1次的ID直接标记为0
- 格式转换:将布尔结果转为1/0的整数格式返回
验证结果
运行函数测试,输出与期望完全一致:
# 测试n=1的情况 data$dupe <- dupe_detect(data, date, id, n = 1) print(data) # 测试n=2的情况 data$dupe <- dupe_detect(data, date, id, n = 2) print(data)
内容的提问来源于stack exchange,提问作者James Martherus
相关产品推荐
相关产品推荐

