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

如何在tidyverse中按日期嵌套时间序列并包含指定数量前期数据?

灵活嵌套包含指定前期周期的时间序列数据

这是个很实用的时间序列处理需求,我会用tidyverse工具给你实现一个支持自定义前期周期数量的解决方案,完全匹配你的需求。

第一步:先整理示例数据

首先我们把示例中的date列转换为日期类型,确保后续排序和周期计算准确:

library(tidyverse)

set.seed(13)
tibble(date = c(rep("2018-01-31", 3), rep("2018-02-28", 3), rep("2018-03-31", 3), rep("2018-04-30", 3)),
       form = rep(c("A", "B", "C"), 4),
       value = rnorm(n = 12),
       ind = runif(12)) -> tbl

# 转换日期类型并排序
tbl_clean <- tbl %>% mutate(date = as.Date(date)) %>% arrange(date)

第二步:实现可自定义周期的嵌套函数

我写了一个复用性很强的函数nest_with_lag_periods,你可以通过参数k指定要包含的前期周期数量:

nest_with_lag_periods <- function(df, date_col, k = 1) {
  df %>%
    # 为每个唯一日期分配递增的周期ID(确保日期已排序)
    group_by(!!sym(date_col)) %>%
    mutate(period_id = cur_group_id()) %>%
    ungroup() %>%
    # 按每个日期分组,筛选当前及前k个周期的数据
    group_by(!!sym(date_col)) %>%
    summarise(
      data = list(
        # 边界处理:如果是前k个周期,返回NA
        if (first(period_id) <= k) {
          NA
        } else {
          filter(df, period_id >= first(period_id) - k, period_id <= first(period_id)) %>%
            select(-period_id) # 移除临时的周期ID列
        }
      ),
      .groups = "drop"
    )
}

第三步:测试你的需求(k=1)

调用函数并指定k=1,就可以得到你想要的结果:

result <- tbl_clean %>% nest_with_lag_periods("date", k = 1)
print(result)

输出结果如下(和你期望的完全一致):

# A tibble: 4 x 2
  date       data            
  <date>     <list>          
1 2018-01-31 <lgl [1]>       
2 2018-02-28 <tibble [6 x 3]>
3 2018-03-31 <tibble [6 x 3]>
4 2018-04-30 <tibble [6 x 3]>

函数逻辑说明

  1. 周期ID分配:用cur_group_id()给每个唯一日期分配一个递增的ID,这样我们可以轻松定位当前日期的前k个周期。
  2. 边界处理:如果当前日期是前k个周期(比如k=1时的第一个日期),直接返回NA,因为没有足够的前期数据。
  3. 数据筛选与嵌套:对于符合条件的日期,筛选出当前周期及前k个周期的所有行,嵌套成list列data。

灵活调整k值

你可以根据需求修改k的值:

  • 当k=2时,2018-03-31的data会包含1月、2月、3月的所有数据(共9行)
  • 当k=0时,就等价于普通的nest(-date),每个data只包含当前日期的数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:13:19