【问题标题】:How can I compute a variable lag value to create a moving average over different time spans?如何计算可变滞后值以创建不同时间跨度的移动平均值?
【发布时间】:2021-03-10 08:42:51
【问题描述】:

我的问题很简单,但我仍然找不到不需要我创建很多不必要的填充行的简单解决方案。

鉴于此数据集:

df <- structure(
  list(
    date = c(
      2015.16666666667,
      2015.33333333333,
      2015.83333333333,
      2016,
      2016.08333333333,
      2016.25,
      2016.33333333333,
      2016.41666666667,
      2016.5,
      2016.66666666667
    ),
    Age = c(
      1,
      2.99999999999818,
      8.99999999999818,
      10.9999999999991,
      11.9999999999982,
      13.9999999999991,
      14.9999999999982,
      16,
      16.9999999999991,
      19
    ),
    year = c(
      2015L,
      2015L,
      2015L,
      2015L,
      2016L,
      2016L,
      2016L,
      2016L,
      2016L,
      2016L
    ),
    month = c(2L, 4L,
              10L, 12L, 1L, 3L, 4L, 5L, 6L, 8L),
    r_Total = c(
      481.02,
      666.36,
      851.7,
      1633.74,
      2155.1,
      2613.74,
      3105.44,
      4429.52,
      5170.88,
      5170.88
    )
  ),
  row.names = c(NA,-10L),
  class = c("tbl_df", "tbl", "data.frame")
)

我想计算过去 12 个月的移动平均值 r_total。但是,数据在 r_total 为 0 的月份中没有行,因此我通常的解决方案不起作用:

library(dplyr)

df %>%
mutate(cummulative_sum = cumsum(r_total), moving_average = (cummulative_sum-lag(cummulative_sum,12)  )/12)

这会计算最近 12 个值的移动平均值,但关键不是过去 12 个月!

lag() 我在这里使用的只是查看有序向量并识别第 -12 位的值。但是,我需要一个函数,它可以从 Age == Age-12 (年龄是自该值开始以来的几个月)为我提供值。

那我该怎么办?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    slider 包非常适合您需要使用另一列来定义时间窗口。

    library(slider)
    df %>% 
      mutate(avg_12mo = slide_index_dbl(r_Total, Age, mean, .before = 11),
             sum_12mo = slide_index_dbl(r_Total, Age, sum, .before = 11))
    
    
    # A tibble: 10 x 7
        date   Age  year month r_Total avg_12mo sum_12mo
       <dbl> <dbl> <int> <int>   <dbl>    <dbl>    <dbl>
     1 2015.  1     2015     2    481.     481.     481.
     2 2015.  3.00  2015     4    666.     574.    1147.
     3 2016.  9.00  2015    10    852.     666.    1999.
     4 2016  11.0   2015    12   1634.     908.    3633.
     5 2016. 12.0   2016     1   2155.    1158.    5788.
     6 2016. 14.0   2016     3   2614.    1814.    7254.
     7 2016. 15.0   2016     4   3105.    2072.   10360.
     8 2016. 16     2016     5   4430.    2465.   14789.
     9 2016. 17.0   2016     6   5171.    2851.   19960.
    10 2017. 19     2016     8   5171.    3141.   25131
    

    【讨论】:

      【解决方案2】:

      我也一直在努力解决其中一些移动窗口问题。在步长或窗口大小不是恒定行数的情况下,tidyverse-approaches 可能会变得很麻烦。

      在这些情况下,虽然我有时会努力将其融入管道方式,但普通循环可能更容易使用。

      第一次尝试循环。与其认为主要输入是 data.frame,不如说我们的主要输入实际上是我们想要回顾 12 个月的日期(恰好来自 df,但您可以选择按日历年之类的)。

      请记住,在使用循环构建结果集时,请使用列表或预先分配的结果向量,而不是通过重复附加来增加 data.frame 或向量。

      df$yearmonth <- with(df, year + (month-1)/12)
      df$cummulative <- NA_real_
      
      
      for (i in seq_along(df$Age)) {
        df$cummulative[i] <- df %>% 
          filter(between(Age, df$Age[i]-11, df$Age[i])) %>% ## any rows within the past 12 months
          pull(r_Total) %>% sum
      }
      
      > df
      # A tibble: 10 x 6
          date   Age  year month r_Total cummulative
         <dbl> <dbl> <int> <int>   <dbl>       <dbl>
       1 2015.  1     2015     2    481.        481.
       2 2015.  3.00  2015     4    666.       1147.
       3 2016.  9.00  2015    10    852.       1999.
       4 2016  11.0   2015    12   1634.       3633.
       5 2016. 12.0   2016     1   2155.       5788.
       6 2016. 14.0   2016     3   2614.       7254.
       7 2016. 15.0   2016     4   3105.      10360.
       8 2016. 16     2016     5   4430.      14789.
       9 2016. 17.0   2016     6   5171.      19960.
      10 2017. 19     2016     8   5171.      25131 
      

      但是不清楚你的平均数是多少;累积的r_total 是否总是除以 12 个月,即使它的总和只有 2 行?

      【讨论】:

        猜你喜欢
        • 2014-12-20
        • 1970-01-01
        • 1970-01-01
        • 2018-05-08
        • 2019-10-27
        • 1970-01-01
        • 2012-11-19
        • 2023-01-12
        • 2020-05-20
        相关资源
        最近更新 更多