我有一个月度股票回报的数据框:
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])
}
}
这种方法有意义还是有更优雅的方式?
答案 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
添加到管道中。