首页 > 解决方案 > 基于日期变量的滚动总和

问题描述

我想根据每个 ID 的确切日期对过去 3 个月的变量的所有值求和。某个 ID 可能有 2 个 obs,另一个 ID 可能有 70 个 obs。例如,在 4 月 15 日,我想一直回溯到 1 月 16 日,并对包括 1 月 16 日和 4 月 15 日在内的这个区间的所有值求和。可能在这个区间上通过 2 次观察,甚至 70 次。

因此,窗口大小永远不会相同,这意味着我不能使用 zoo 包中的 rollapply。

这是一个带有预期输出的小示例数据。

df <- structure(list(id = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 
3, 3, 3, 3, 3, 3, 3, 3), date = c("01/01/2015", "01/02/2015", 
"15/02/2015", "01/03/2015", "01/04/2015", "01/01/2015", "01/02/2015", 
"15/02/2015", "20/02/2015", "01/03/2015", "14/03/2015", "01/04/2015", 
"01/01/2015", "10/02/2015", "15/02/2015", "20/02/2015", "25/02/2015", 
"01/03/2015", "10/03/2015", "20/03/2015", "01/04/2015"), value = c(106, 
57, 43, 105, 180, 109, 36, 102, 97, 97, 113, 83, 178, 19, 80, 
167, 40, 5, 30, 124, 8), expected = c(106, 163, 206, 311, 385, 
109, 145, 247, 344, 441, 554, 528, 178, 197, 277, 444, 484, 489, 
519, 643, 473)), row.names = c(NA, -21L), class = c("tbl_df", 
"tbl", "data.frame"))

标签: r

解决方案


widthin可以是宽度向量,rollapply我们可以使用 来计算findInterval

library(dplyr)
library(lubridate)
library(zoo)

df %>%
  group_by(id) %>%
  mutate(date = dmy(date), 
         expected2 = rollapplyr(value, 
          width = 1:n() - findInterval(date - months(3), date), 
          FUN = sum, na.rm = TRUE, fill = NA)) %>%
  ungroup

给予:

# A tibble: 21 x 5
      id date       value expected expected2
   <dbl> <date>     <dbl>    <dbl>     <dbl>
 1     1 2015-01-01   106      106       106
 2     1 2015-02-01    57      163       163
 3     1 2015-02-15    43      206       206
 4     1 2015-03-01   105      311       311
 5     1 2015-04-01   180      385       385
 6     2 2015-01-01   109      109       109
 7     2 2015-02-01    36      145       145
 8     2 2015-02-15   102      247       247
 9     2 2015-02-20    97      344       344
10     2 2015-03-01    97      441       441
# ... with 11 more rows

推荐阅读