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

如何在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()
}

逻辑说明

  1. 分组处理:按ID分组,仅针对同一ID的日期记录做判断
  2. 窗口检查:对每个ID的所有日期,判断是否存在与当前行日期差≤n天的其他记录
  3. 重复判定:
    • 若同一ID在时间窗口内出现多次,或同一日期内出现多次,标记为1
    • 仅出现1次的ID直接标记为0
  4. 格式转换:将布尔结果转为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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 02:03:59