使用plyr / dplyr每两年计算一次平均值

时间:2014-04-07 18:14:47

标签: r plyr dplyr

我有一个庞大的数据集,包括34年来500股的每日回报。我首先运行ddply来创建年度中位数和返回列:

annual <- ddply(data, c("TICKER", "year"), summarize, 
                median_data = median(RETX),
                return = prod(1 + RET))

目前的数据如下:

  TICKER year median_data    return
1      A 2000  -0.0081645 0.6717770 
2      A 2001  -0.0036845 0.5207290 
3      A 2002  -0.0069040 0.6299523
4      A 2003   0.0036585 1.6280659  
5      A 2004   0.0000120 0.8242153  
6      A 2005   0.0004025 1.3813425  

现在我想创建一个新列,其中包含过去两年每个股票代码的median_data平均值:

  TICKER year median_data    return    avg_median
1      A 2000  -0.0081645 0.6717770           NA
2      A 2001  -0.0036845 0.5207290    -0.0036845
3      A 2002  -0.0069040 0.6299523    -0.0105885
4      A 2003   0.0036585 1.6280659           ...
5      A 2004   0.0000120 0.8242153  
6      A 2005   0.0004025 1.3813425  

对此的任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:3)

dplyr解决方案:

为了完整性+正确性,这里是dplyr方式,因为此问题有一个dplyr标记。除非我遗漏了某些东西,否则dvdkamp的解决方案只有在你拥有一支股票时才有效。

数据:500只股票,34年

df <- expand.grid(
    year = 1980:2014,
    TICKER = paste0(expand.grid(letters,letters)[1:500,1],
                   expand.grid(letters,letters)[1:500,2])
            )
df$median_data <- rnorm(1:500)
df <- df[,c(2,1,3)]

看起来像这样:

  TICKER year median_data
1     aa 1980   0.5734215
2     aa 1981   1.2102109
3     aa 1982   0.8643419
4     aa 1983   0.7645975
5     aa 1984   0.4004396
6     aa 1985  -1.0195817

第一组进入股票

by_ticker <- df %>% group_by(TICKER)

使用lag()生成资料:

今年和上一年的意思。请注意默认的lag(,n=1) (最近2年)

by_ticker %>% 
         mutate(mean_last2y_incl = ( median_data + lag(median_data) ) / 2 )

去年和前一年的平均值。 (最近2年独家)

by_ticker %>% 
         mutate(mean_last2y_excl = ( median_data + lag(median_data, n=2) ) / 2 )

请参阅:http://cran.rstudio.com/web/packages/dplyr/vignettes/window-functions.html了解更多信息。

答案 1 :(得分:1)

window_size <- 2 # number of years to average over

data$avg_median <- filter(data$median_data, 
rep(1,window_size)/window_size,  ## filter coefficients (1/2, 1/2)
sides = 1) ## do the average for years before and including this year