滚动平均值具有不同的观察数量

时间:2017-02-10 08:32:38

标签: r moving-average

我正在尝试为过去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值的所有行的平均值在20150601和20160101之间。当没有先前的值可用时,我假设平均值为零。

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

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:0)

也许这会有所帮助:

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