不同观察次数的滚动平均值

Rolling mean with differing number of observations

我正在尝试为过去 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 和日期值 20160101,我想获得具有相同 ID 的所有行的平均值以及DATE 值介于 20150601 和 20160101 之间。如果没有以前的值可用,我假设平均值为零。

我想过使用某种扩展网格的方法,但由于我有很多 ID(接近 30.000),因此在 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)

这里我用的是dplyr。我 inner_join 本身 table,然后过滤相关的前几行,源数据中的每行,并计算平均值。

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

6 个月 window 的计算方法是 DATE 减去 182 天。您也可以使用 lubridate 使其成为以月为单位的句点。就我个人而言,我更喜欢使用固定的 window 天数,这不取决于每个月的天数。

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