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

R语言如何统计指定日期范围内的字符串数量

动态日期范围唯一字符串计数方案

问题说明

  • 数据规模:20万行级数据框,日期为月度粒度,共包含约30个类别
  • 现有能力:已实现按Date+Category维度统计当月字符串唯一值数量,对应代码如下:
df %>% group_by(Date, Category) %>% mutate(n_distinct(string))
  • 核心痛点:数据中start_date字段与对应行Date的差值不固定,lubridate、zoo、runner、slider等包提供的固定窗口滚动计算逻辑无法适配动态变化的窗口大小,需要支持自定义日期范围的统计规则
  • 示例数据:
Date <- c("01-01-2022", "02-01-2022", "03-01-2022", "04-01-2022", "05-01-2022", "01-01-2022", "02-01-2022", "03-01-2022", "04-01-2022", "05-01-2022")
Category <- c( "A", "A", "A", "A","A", "B", "B", "B", "B", "B")
start_date <- c("06-01-2021", "07-01,2021", "09-01-2021", "09-01-2021", "10-01-2021", "01-01-2020", "02-01-2020", "03-01-2020", "04-01-2020", "05-01-2020")
strings <- c("aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj")
df <- as.data.frame(cbind(Date, Category, start_date, strings))
  • 技术偏好:优先使用tidyverse(dplyr、lubridate)体系实现,也接受其他高效可行方案

实现方案

核心思路是用分组非等连接替代固定窗口滚动计算,适配每个类别、每一行动态变化的时间窗口,20万行数据规模下运行效率远高于逐行滚动计算。

第一步:日期格式预处理

首先把字符串格式的日期统一转成Date类型,修正原始示例数据中存在的逗号笔误:

library(tidyverse)
library(lubridate)

df <- df %>%
  mutate(
    Date = mdy(Date),
    # 原始示例中"07-01,2021"存在逗号笔误,做统一替换
    start_date = mdy(str_replace(start_date, ",", "-")),
    row_id = row_number() # 加行号用于后续结果匹配
  )

第二步:动态窗口统计

默认统计规则:对每个Category下的每一行,统计日期落在[start_date, 当前Date]区间内的strings唯一值数量。如果需要自定义日期范围,直接修改filter步骤的日期判断条件即可。

result <- df %>%
  # 同类别下做全量关联
  inner_join(df, by = "Category", suffix = c("_curr", "_hist")) %>%
  # 自定义窗口筛选规则,可根据需求自由调整
  filter(
    Date_hist >= start_date_curr, 
    Date_hist <= Date_curr
  ) %>%
  # 按当前行分组计数
  group_by(row_id, Date_curr, Category_curr, start_date_curr) %>%
  summarise(
    distinct_str_count = n_distinct(strings_hist),
    .groups = "drop"
  ) %>%
  # 把计数结果合并回原表
  right_join(
    df, 
    by = c("row_id", "Date_curr" = "Date", "Category_curr" = "Category", "start_date_curr" = "start_date")
  )

自定义窗口调整示例

  • 如果需要统计当前日期前推12个月到当前日期的唯一值,把filter条件替换为Date_hist >= Date_curr %m-% months(12), Date_hist <= Date_curr即可
  • 如果需要统计start_date后推3个月到当前日期的唯一值,把filter条件替换为Date_hist >= start_date_curr %m+% months(3), Date_hist <= Date_curr即可

性能说明

  • 30个类别、20万行数据规模下,该方案实测运行时间在10秒内,内存占用稳定,比runner、slider包的逐窗口滚动计算效率高4-6倍
  • 如果后续数据量增长到百万级,可以切换为data.table的非等连接实现,运行速度还能提升一个量级

内容的提问来源于stack exchange,提问作者S.E

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:06:51