我正在模拟价格时间序列,其中时间范围基本上是每个月包含20个工作日和12个月是一年。我现在想要计算这个价格的滚动平均值,总是基于该月的第一天。
我确实有一个有效的解决方案,但想知道是否有更优雅或更快的解决方案。
dt.oil.price
Period Month Day.Month Oil.Price Oil.Supply Risk.Free.Interest
1: 1 1 1 39.4560000 NA 0.08642857
2: 2 1 2 3.7889460 NA 0.08642857
3: 3 1 3 51.0748751 NA 0.08642857
4: 4 1 4 60.6282853 NA 0.08642857
5: 5 1 5 35.7267224 NA 0.08642857
6: 6 1 6 26.1868977 NA 0.08642857
7: 7 1 7 32.6488136 NA 0.08642857
8: 8 1 8 42.6397549 NA 0.08642857
9: 9 1 9 18.8969991 NA 0.08642857
...
20: 20 1 20 8.8036135 NA 0.08642857
21: 21 2 1 2.5559526 NA 0.08642857
22: 22 2 2 24.3996401 NA 0.08642857
...
40: 40 2 20 41.2988566 NA 0.08642857
41: 41 3 1 20.8012327 NA 0.08642857
42: 42 3 2 70.5297726 NA 0.08642857
只是为了让您了解数据的结构。要创建具有60个句点的上述数据结构:
set.seed(1);
dt.oil.price <- as.data.table(cbind( Period = 1:60,
Month = as.integer(rep(1:(60/20), each = 20))[1:60],
Oil.Price=rnorm(3*20,mean = 50, sd = 10)))
dt.oil.price[,"Day.Month" := rank(Period),by="Month"]
使用以下代码,我可以选择一个月的所有首日,并计算这些天的油价平均值:
dt.oil.price[ Day.Month == 1, mean(Oil.Price)]
在下一步中,我使用另一个辅助列“Num.Months”来相应地对月数进行排名,
dt.oil.price[Day.Month == 1 & Period <= 8921,"Num.Months" := rank(-Period)]
然后我可以通过对此
进行子集化来选择平均计算的最后两个月dt.oil.price[Day.Month == 1 & Period <= 8921,"Num.Months" := rank(-Period)][Num.Months <= 2, Oil.Price]
代码段,允许在过去三个月内不使用显式帮助列来计算均值:
dt.oil.price[Day.Month == 1 & Period <= 60, {Num.Months = rank(-Period); list("Period" = Period, "Month" = Month, "Oil.Price" = Oil.Price, "Num.Months" = Num.Months)}][Num.Months <=12, mean(Oil.Price)]
我希望我的步骤都清晰明确,我也希望实现。还可以通过定义例如周期来动态地计算移动平均值,然后计算该周期之前的最近12个月的移动平均值。这可以通过将data.table仅设置为小于定义的时段的时段然后为此data.table子集计算“Num.Months”来实现。