按月拆分的滚动/移动平均值

3

我想要计算每月的滚动/移动平均值,与ggplot2包中的经济数据一起使用。例如,我想构建一个时间序列来表示每个月份的3年滚动平均值。

library(ggplot2)
df = economics
df$month =  as.POSIXlt(df$date)$mon+1

当我手动将数据按月份拆分时,我得到了我想要的准确结果:

library(zoo)
df.test = subset(df, month==1)
df.test$uempmed.ma = rollapply(df.test$unemploy,  width=3, FUN=mean, na.rm=T, 
                               fill=NA, align="right") 


  head(df.test)

         date   pce    pop psavert uempmed unemploy year month uempmed.ma
8  1968-01-31 534.7 199920     9.5     4.5     3001 1968     1         NA
20 1969-01-31 590.2 201881     6.5     4.9     2692 1969     1         NA
32 1970-01-31 635.7 204008     8.1     4.5     3453 1970     1   3048.667
44 1971-01-31 681.3 206668     9.9     6.3     4903 1971     1   3682.667
56 1972-01-31 738.4 209061     9.4     6.6     4928 1972     1   4428.000
68 1973-01-31 828.5 211120     9.5     5.2     4452 1973     1   4761.000

但是,当我尝试使用plyr软件包一次性处理所有月份时......

library(plyr)
df2 = ddply(df, .(month), mutate,
            uempmed.ma = rollapply(df$uempmed,  3, FUN=mean, na.rm=T, 
                                   fill=NA, align="right") 
)

当执行该操作时,会返回以下错误:

Error: wrong result size (478), expected 40 or 1

我知道这应该很简单,但是我却被难住了。
最终,我希望移动平均数列(即 uempmed.ma )是滞后的--也就是说,不包括当前年份在内的计算。例如,上面提到的1971-01-31的值应该是uempmed在1968-01-31、1969-01-31和1970-01-31时期的平均值。
任何帮助将不胜感激。
1个回答

7

dplyr(新一代的plyr)似乎可行

library(zoo)
library(dplyr)
df %>%
  group_by(month) %>%
  mutate(uempmed.ma = rollapply(unemploy, width = 3, 
         FUN = mean, na.rm = TRUE, fill = NA, align = "right"))

您也可以使用基础 R 来高效地完成操作(肯定比使用 plyr 更高效)

transform(df, uempmed.ma = ave(unemploy, month, 
                               FUN = function(x) rollapply(x, width = 3, 
                                                 FUN = mean, na.rm = TRUE, 
                                                 fill = NA, align = "right")))

或者一个额外的解决方案:使用data.table包。
library(data.table)
setDT(df)[, uempmed.ma := rollapply(unemploy,  width = 3, 
                          FUN = mean, na.rm = TRUE, fill = NA, 
                          align = "right"), 
          by = month]

请问是否有好的想法能够将该系列推迟一年(即在计算中不包括今年)?谢谢。 - MikeTP
我不确定你的意思。那是一个新问题吗?你说的“current year”是什么意思?或许可以加上一些期望的输出结果? - David Arenburg
不要忘记 library(zoo) - Robert Krzyzanowski
@RobertKrzyzanowski,你可能是对的,尽管我只是从原始帖子中接手完成的。但我还是会添加的。 - David Arenburg
@David Arenburg:为了澄清,你的解决方案非常好。但是,我还在寻找一种使移动平均线成为跟踪型的方法。也就是说,它应该代表前三年的平均值,而不包括当前年/月的值在移动平均线中。 - MikeTP
1
也许你可以在开头添加 NA 并删除最后一个值,类似这样:c(NA, head(rollapply(unemploy, width = 3, FUN = mean, na.rm = TRUE, fill = NA, align = "right"), -1)) - David Arenburg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接