不同观察次数的滚动平均值
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
我正在尝试为过去 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