我正在尝试为过去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年内扩展网格会产生巨大的网格。
答案 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)