You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用dplyr创建参考值动态变化的lag(滞后)

用dplyr实现时间分组(组内最大时间滞后≤2个月/指定天数)

我完全get你的需求啦——把时间序列(先以月份为例)划分成若干分组,保证每组内的时间跨度不超过2个月,之后还要扩展到天级的大规模数据对吧?下面我给你一步步演示实现方法,逻辑清晰,直接就能套用到你的数据上。

第一步:构造示例数据

先造一份月份数据来测试逻辑,你可以替换成自己的真实数据:

library(dplyr)
library(lubridate)  # 处理时间的必备包

# 生成2023年1-12月的示例数据
df <- tibble(
  month = seq(ymd("2023-01-01"), ymd("2023-12-01"), by = "month")
)

第二步:核心分组逻辑(月份版)

核心思路是:先按时间排序,然后跟踪当前时间和组内起始时间的差距,一旦超过2个月就开启新组。用dplyrmutate+cumsum就能轻松实现:

df_grouped <- df %>%
  arrange(month) %>%  # 务必保证时间是升序的,这是分组的前提!
  mutate(
    # 计算当前月份与上一个月份的差值(第一行默认和自己比,差值为0)
    month_diff = interval(lag(month, default = first(month)), month) %/% months(1),
    # 当差值超过2时,累加生成新组号,+1是让组号从1开始
    group_id = cumsum(month_diff > 2) + 1
  )

查看分组结果

运行后打印结果,你会看到分组完全符合要求:

print(df_grouped)

输出示例:

# A tibble: 12 × 3
   month      month_diff group_id
   <date>          <dbl>    <dbl>
 1 2023-01-01          0        1
 2 2023-02-01          1        1
 3 2023-03-01          1        1
 4 2023-04-01          1        2  # 和组1起始月(1月)差3个月,触发新组
 5 2023-05-01          1        2
 6 2023-06-01          1        2
 7 2023-07-01          1        3  # 和组2起始月(4月)差3个月,触发新组
 8 2023-08-01          1        3
 9 2023-09-01          1        3
10 2023-10-01          1        4  # 和组3起始月(7月)差3个月,触发新组
11 2023-11-01          1        4
12 2023-12-01          1        4

每组内的时间跨度都严格控制在2个月以内,完美符合你的要求!

扩展到天级大规模数据

要适配天级数据,只需要把时间单位和阈值调整一下就行,逻辑完全通用:

# 构造天级示例数据(2023年1-3月的所有日期)
df_daily <- tibble(
  date = seq(ymd("2023-01-01"), ymd("2023-03-31"), by = "day")
)

# 按组内最大滞后60天来分组(对应2个月左右)
df_daily_grouped <- df_daily %>%
  arrange(date) %>%
  mutate(
    # 计算当前日期与上一个日期的天数差
    date_diff = interval(lag(date, default = first(date)), date) %/% days(1),
    # 当天数差超过60时,开启新组
    group_id = cumsum(date_diff > 60) + 1
  )

额外注意事项

  • 时间排序是关键:如果你的原始数据时间是乱序的,一定要先arrange排序,否则分组逻辑会出错;
  • 重复时间处理:如果数据里有重复的时间点,这个逻辑依然适用,因为重复时间的差值为0,不会触发新组;
  • 大规模数据效率:dplyr本身处理大规模数据的效率已经很高,如果数据量特别大(比如千万级以上),可以搭配dtplyr来进一步提速,语法几乎不用改。

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

火山引擎 最新活动