【问题标题】:Rolling mean with differing number of observations具有不同观察次数的滚动平均值
【发布时间】:2017-02-10 08:32:38
【问题描述】:

我正在尝试为过去 6 个月的数据集构建滚动平均值。 这些数据是每天的数据,有超过 100.000 行,我在下面提供了一个示例。

# A tibble: 100 × 5
       ID    MONTH       DATE VALUE   R_MEAN
   <fctr>    <dbl>     <date> <dbl>    <dbl>
1     634 20160200 2016-02-03     2 0.000000
2    1700 20150300 2015-03-02     3 0.000000
3    1700 20150400 2015-04-01     7 3.000000
4    1700 20150400 2015-04-09     1 5.000000
5    1700 20150700 2015-07-02    26 3.666667
6    1700 20150800 2015-08-03     1 9.250000
7    1700 20150900 2015-09-01     2 7.600000
8    1700 20151000 2015-10-01     5 7.400000
9    1700 20151000 2015-10-07    10 7.833333
10   1700 20151100 2015-11-02     8 8.800000
# ... with 90 more rows

我的目标是创建过去 6 个月的移动平均值,例如,对于 ID:X 和 DATE 值为 20160101,我想获取所有具有相同 ID 和 DATE 值的行的平均 VALUE介于 20150601 和 20160101 之间。当没有以前的值可用时,我假设平均值为零。

我曾想过使用某种扩展网格的方法,但由于我有很多 ID(接近 30.000),因此在 2 年内每天扩展网格会产生巨大的网格。

【问题讨论】:

    标签: r moving-average


    【解决方案1】:

    这里我使用dplyr。我inner_join对自己的表,然后过滤相关的先前行,源数据中的每一行,并计算平均值。

    最后我将left_join原始数据放在处理后的数据上,并用coalesce替换NA

    6 个月窗口的计算方法是从 DATE 中减去 182 天。您也可以使用lubridate 将其设为几个月。就我个人而言,我更喜欢使用固定的天窗,这不取决于每个月的天数不同。

    str <- '
    row ID  MONTH DATE  VALUE R_MEAN
    1 634 20160200 2016-02-03     2 0.000000
    2 1700 20150300 2015-03-02     3 0.000000
    3 1700 20150400 2015-04-01     7 3.000000
    4 1700 20150400 2015-04-09     1 5.000000
    5 1700 20150700 2015-07-02    26 3.666667
    6 1700 20150800 2015-08-03     1 9.250000
    7 1700 20150900 2015-09-01     2 7.600000
    8 1700 20151000 2015-10-01     5 7.400000
    9 1700 20151000 2015-10-07    10 7.833333
    10  1700 20151100 2015-11-02     8 8.800000
    '
    
    file <- textConnection(str)
    
    raw <- read.table(file, header = T)
    
    library(dplyr)
    
    df <- raw %>% mutate(DATE = as.Date(DATE,'%Y-%m-%d'))
    
    prev <- df %>% inner_join(df, by = 'ID') %>%
      filter(DATE.y > DATE.x-182, DATE.y < DATE.x) %>%
      group_by(row.x) %>% summarise(meanVALUE = mean(VALUE.y)) %>%
      rename(row = row.x)
    
    df %>% left_join(prev, by='row') %>% mutate(meanVALUE = coalesce(meanVALUE,0))
    

    结果:

       row   ID    MONTH       DATE VALUE   R_MEAN meanVALUE
    1    1  634 20160200 2016-02-03     2 0.000000  0.000000
    2    2 1700 20150300 2015-03-02     3 0.000000  0.000000
    3    3 1700 20150400 2015-04-01     7 3.000000  3.000000
    4    4 1700 20150400 2015-04-09     1 5.000000  5.000000
    5    5 1700 20150700 2015-07-02    26 3.666667  3.666667
    6    6 1700 20150800 2015-08-03     1 9.250000  9.250000
    7    7 1700 20150900 2015-09-01     2 7.600000  8.750000
    8    8 1700 20151000 2015-10-01     5 7.400000  7.500000
    9    9 1700 20151000 2015-10-07    10 7.833333  7.000000
    10  10 1700 20151100 2015-11-02     8 8.800000  8.800000
    

    【讨论】:

      【解决方案2】:

      也许这会有所帮助:

         for (i in 1:levels(df$ID))
           mean(df$value[df$DATE>(Sys.date()-182) & 
                         df$ID==levels(df$ID)[i]],
                 na.rm=T)
      

      【讨论】:

      • 我想要每行中 DATE 值在过去 6 个月内的滚动平均值。所以我不想在今天的基础上回顾过去的6个月。仍然感谢您的回复。
      猜你喜欢
      • 2021-02-26
      • 1970-01-01
      • 2015-10-27
      • 2017-06-14
      • 1970-01-01
      • 2021-02-08
      • 2016-05-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多