计算每月回报数据框的3个月回报

时间:2017-12-05 04:02:51

标签: r dataframe apply

我有一个月度股票回报的数据框:

d<-data.frame(replicate(5,sample(rnorm(1),6,rep=TRUE)))

现在我想以下列方式将这些回报转换为n个月回报(例如,对于n = 3):

d[1,1]=(1+d[1,1])*(1+d[2,1])*(1+d[3,1])
d[2,1]=(1+d[2,1])*(1+d[3,1])*(1+d[4,1])
d[3,1]=(1+d[3,1])*(1+d[4,1])*(1+d[5,1])

然后对下一栏也一样:

d[1,2]=(1+d[1,2])*(1+d[2,2])*(1+d[3,2])
d[2,2]=(1+d[2,2])*(1+d[3,2])*(1+d[4,2])
d[3,2]=(1+d[3,2])*(1+d[4,2])*(1+d[5,2])

我想你明白了。

现在,我正在考虑的方式如下:

apply(d, 2, fun)

其中fun被定义为:

fun<-function(df_column)
{
  # Loop over df_column rows
 for (row in 1:nrow(df_column)) {
   d[row]=(1+d[row])*(1+d[row+1])*(1+d[row+2])
 }
}

这种方法有意义还是有更优雅的方式?

2 个答案:

答案 0 :(得分:2)

根据您喜欢的内容,尝试使用其中一种形式的rollapply。第一个将NAs放在最后两行中。第二个用部分产品填充它们,第三个用最后两行填充。 3参数指定滚动产品的宽度,如果要尝试其他宽度,可以更改。有关详细信息,请参阅?rollapply

library(zoo)

rollapplyr(d + 1, 3, prod, align = "left", fill = NA)

rollapplyr(d + 1, 3, prod, align = "left", partial = TRUE)

rollapplyr(d + 1, 3, prod, align = "left")

答案 1 :(得分:1)

您可以使用east-1-1: 50 * east-1-1: 50 east-1-2: 8 east-1-3: 58 * east-1-3: 58 east-1-4: 5 east-1-5: 5 east-1-6: 4 east-1-7: 30 * east-1-7: 30 west-1-1: 4 west-1-10: 50 * west-1-10: 50 south-1-2: 30 * south-1-2: 30 east-1-1: 50 * east-1-2: 8 east-1-3: 58 * east-1-4: 5 east-1-5: 5 east-1-6: 4 east-1-7: 30 * west-1-1: 4 west-1-10: 50 * south-1-2: 30 * 来实现您的目标。

purrr::map_df
  

N.B。当你向前看两条记录时,请注意最后两行只会产生dplyr::lead。如果您希望将其排除在外,可以将library(dplyr) library(purrr) set.seed(42) df <- data.frame(replicate(5, rnorm(6))) df %>% map_df(function(x) { (1 + x) * (1 + lead(x, 1)) * (1 + lead(x, 2)) }) # # A tibble: 6 x 5 # X1 X2 X3 X4 X5 # <dbl> <dbl> <dbl> <dbl> <dbl> # 1 1.4068610 6.863243 -0.2430606 -2.3172461 1.2246900 # 2 0.9688954 2.561324 1.0225645 -1.2568729 -0.3228241 # 3 3.1256224 6.520767 1.0148172 -0.4485965 -0.8276191 # 4 2.0496361 7.100212 -1.9395879 -1.4328679 -0.4011510 # 5 NA NA NA NA NA # 6 NA NA NA NA NA NA添加到管道中。