我遇到了一个小问题。假设我有一个动物园数据集,其结构如下:
df<-data.frame(r1=rnorm(25), r2=rnorm(25))
df<-zoo(df, as.Date(seq(from=as.Date("1980-01-01"), to=as.Date("1983-02-01"), by="1 month")))
我想按照以下方式计算每月r1和r2的季度平均值(伪代码):
rx (Jan. 1980) = rx (Jan. 1980)
rx (Feb. 1980) = average [ rx (Jan. 1980), rx (Feb. 1980) ]
rx (Mar. 1980) = average [ rx (Jan. 1980), rx (Feb. 1980), rx (Mar. 1980)]
rx (Apr. 1980) = rx (Apr. 1980)
rx (May 1980) = average [ rx (Apr. 1980), rx (May 1980) ]
rx (Jun. 1980) = average [ rx (Apr. 1980), rx (May 1980), rx (Jun. 1980)]
等。 - 也就是说,我希望将每个月的价值替换为季度中实现的观察值,直至本季度的这一点。
我已尝试过rollapply(第2个月参数width = 2,align =“right”;对于第3个月,宽度= 3),但我觉得我无法找出最聪明的方法它,或者有更好/更快的方式来做到这一点......任何建议都将受到高度赞赏!
谢谢,菲利普
答案 0 :(得分:2)
不知道它是否是最好的方式。但它的确有效!我尝试使用rollapply,最后使用可变宽度参数使其工作。
rollapply(df, ((month(index(df)) - 1) %% 3) + 1, mean, align="right")
答案 1 :(得分:0)
除非我遗漏了某些东西,否则就是这样:
fac <- as.numeric(cut(as.Date(attributes(df)$index, "%Y-%m-%d"), "quarter"))
split_df <- split(df, fac)
newdf <- do.call(rbind, lapply(split_df,
function(x) {
x$r1 <- cumsum(x$r1) / seq_along(x$r1);
x$r2 <- cumsum(x$r2) / seq_along(x$r2);
return(x)}))
#newdf #df
# r1 r2 # r1 r2
#1980-01-01 -0.056649139 -0.816007382 #1980-01-01 -0.05664914 -0.81600738
#1980-02-01 0.008543219 -0.423027620 #1980-02-01 0.07373558 -0.03004786
#1980-03-01 0.395468481 -0.755660995 #1980-03-01 1.16931901 -1.42092775
#1980-04-01 -0.375906206 -1.011203256 #1980-04-01 -0.37590621 -1.01120326
#1980-05-01 -0.131085288 -0.876251192 #1980-05-01 0.11373563 -0.74129913
#1980-06-01 0.025572095 -0.347781855 #1980-06-01 0.33888686 0.70915682