【问题标题】:Sum of elements in a forward looking rolling window by month前瞻滚动窗口中按月计算的元素总和
【发布时间】:2021-03-01 04:42:16
【问题描述】:

我有以下带有列的 data.frame:Id、Month、有

library(dplyr)

dt <- read.table(header = TRUE, text = '
Id  Month    have   want
1   01-Jan-2018  1.000000000000000   1.234567901220000 
1   01-Feb-2018  0.200000000000000   0.234567901233000 
1   01-Mar-2018  0.030000000000000   0.034567901234400 
1   01-Apr-2018  0.004000000000000   0.004567901234550 
1   01-May-2018  0.000500000000000   0.000567901234566 
1   01-Jun-2018  0.000060000000000   0.000067901234566 
1   01-Jul-2018  0.000007000000000   0.000007901234566 
1   01-Aug-2018  0.000000800000000   0.000000901234566 
1   01-Sep-2018  0.000000090000000   0.000000101234566 
1   01-Oct-2018  0.000000010000000   0.000000011234566 
1   01-Nov-2018  0.000000001100000   0.000000001234566 
1   01-Dec-2018  0.000000000120000   0.000000000134566 
1   01-Jan-2019  0.000000000013000   0.000000000014566 
1   01-Feb-2019  0.000000000001400   0.000000000001566 
1   01-Mar-2019  0.000000000000150   0.000000000000166 
1   01-Apr-2019  0.000000000000016   0.000000000000016 
2   01-Jan-2018 1337.00 1338.00
2   01-Feb-2018 1.00    1.00
3   01-Jan-2018  5.000000000000000000    5.000000000000000 
') %>% mutate(Month=as.Date(Month, format='%d-%b-%Y')

我想以编程方式计算 12 个月前瞻滚动窗口中按月计算的元素总和,并按 Id 分组,如 want 列所示。如果滚动观察窗口小于 12 个月,则应忽略缺失的元素。

对于奖励积分,该解决方案是否还允许缺少月份,例如:

dt <- read.table(header = TRUE, text = '
Id  Month    have   want
1   01-Jan-18    1.000000000000000   1.200000000000000 
1   01-Dec-18    0.200000000000000   0.230000000000000 
1   01-Jan-19    0.030000000000000   0.030000000000000 
') %>% mutate(Month=as.Date(Month, format='%d-%b-%Y')

我尝试了不同的解决方案,例如zoo 包中的rollapplyr() 和 runner 包中的一些功能,但它似乎没有给我我需要的东西。

【问题讨论】:

    标签: r dplyr time-series zoo rolling-computation


    【解决方案1】:

    您可以将zoorollaplypartial = TRUE 一起使用

    library(dplyr)
    
    dt %>%
      group_by(Id) %>%
      tidyr::complete(Month = seq(min(Month), max(Month), "month")) %>%
      mutate(result = zoo::rollapply(have, 12, sum, na.rm = TRUE, 
                                     align = 'left', partial = TRUE)) -> result
    result
    

    如果您有每个 Id 的每个月的数据,就像共享的示例中一样,您可以删除 complete 步骤。

    【讨论】:

      【解决方案2】:

      我建议在这种情况下使用runner 包。 runner 函数让您计算滚动窗口的时间完全可控。 k 是窗口长度,lag 是窗口的滞后,在 idx 中指定窗口所依赖的索引列。

      library(runner)
      
      dt %>%
        group_by(Id) %>%
        mutate(want2 = runner(
          .,
          f = function(x) sum(x$have),
          k = 12,    # or "12 months"
          lag = -11, # or "-11 months"
          idx = Month)
        )
      
      # # A tibble: 19 x 5
      # # Groups:   Id [3]
      #    Id Month          have     want    want2
      # <int> <date>        <dbl>    <dbl>    <dbl>
      #   1     1 2018-01-01 1.00e+ 0 1.23e+ 0 1.00e+ 0
      #   2     1 2018-02-01 2.00e- 1 2.35e- 1 2.00e- 1
      #   3     1 2018-03-01 3.00e- 2 3.46e- 2 3.00e- 2
      #   4     1 2018-04-01 4.00e- 3 4.57e- 3 4.00e- 3
      #   5     1 2018-05-01 5.00e- 4 5.68e- 4 5.00e- 4
      #   6     1 2018-06-01 6.00e- 5 6.79e- 5 6.00e- 5
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-14
        • 1970-01-01
        • 2020-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多