R中每5天滚动标准偏差

时间:2014-08-31 11:14:29

标签: r standard-deviation

我有一个时间序列数据框,看起来像

2014-02-05 2014-02-06 2014-02-07 2014-02-12 2014-02-14 2014-02-17 2014-02-18 2014-02-19 ......
    0.0379    -0.0008     0.0352     0.0379     0.0392     0.0173     0.0360     0.0371

我想计算R中此列表中每第5天数据的移动标准差。我的意思是,我希望选择样本中的样本,样本1 [1] = 2014-02-05,0.0379 ,sample1 [2] = 2014-02-12,0.0379 .....然后找到此样本的标准差,然后使用滚动标准偏差继续下一个日期,即sample2 [1] = 2014-02 -06,-0.0008,sample2 [2] = 2014-02-12,0.0379并找到该列表的标准差,依此类推。由于可用日期不规则,我不能使用seq(1:l,by =)。在rollapply中,函数将采用每个连续的数字来计算标准偏差。有没有办法以有效的方式从该列表中每隔5天采样一次数据,或以某种方式修改标准差函数,使其每隔5天选择一次数据,然后计算可用数据的标准差。任何有关这方面的建议都将受到高度赞赏。

2 个答案:

答案 0 :(得分:5)

重述问题我假设您要填写缺失日期,然后如果z是结果系列计算以下

sd(c(z[1], z[6], z[11], z[16], z[21]))
sd(c(z[2], z[7], z[12], z[17], z[22]))
etc.

但只保留sample1中有时开始的那些sd。

如果这不是问题的意图,请通过进一步的解释和提供输入和输出的实际例子来澄清。

回答创建每日网格g并与sample1合并,填写最后一行,并填写完整系列z。 (请注意,如果点的间隙大于4天,那么我们不会填补这些空白,因为这会涉及在sd中多次包含点。)然后使用rollapply计算所需的sd仅保留原来的时间。

g <- zoo(, seq(start(sample1), end(sample1), "day"))
z <- na.locf(merge(sample1, g), fromLast = TRUE, maxgap = 4)
r <- rollapply(z, 21, function(x) sd(x[seq(1, 21, 5)]), align = "left")
r[time(sample1)]

注意 rollapply语句也可以这样写:

r <- rollapply(z, list(seq(0, length = 5, by = 5)), sd)

因为width参数可以指定为包含偏移量矢量的列表。

更新重新阅读问题后再次修改。还提供了备用rollapply表达式。

答案 1 :(得分:0)

以下可能有用:

xx = structure(c(0.0379, -8e-04, 0.0352, 0.0379, 0.0392, 0.0173, 0.036, 
0.0371), .Names = c("2014-02-05", "2014-02-06", "2014-02-07", 
"2014-02-12", "2014-02-14", "2014-02-17", "2014-02-18", "2014-02-19"
))

xx
2014-02-05 2014-02-06 2014-02-07 2014-02-12 2014-02-14 2014-02-17 2014-02-18 2014-02-19 
    0.0379    -0.0008     0.0352     0.0379     0.0392     0.0173     0.0360     0.0371 
yy = as.numeric()
for(i in 5:length(xx)){
    yy[i]= sd(xx[(i-4):i])
}
yy
[1]          NA          NA          NA          NA 0.017212408 0.017278108 0.008982038 0.009130991

对于数据框版本:

ddf = structure(list(date = structure(1:8, .Label = c("2014-02-05", 
"2014-02-06", "2014-02-07", "2014-02-12", "2014-02-14", "2014-02-17", 
"2014-02-18", "2014-02-19"), class = "factor"), value = c(0.0379, 
-8e-04, 0.0352, 0.0379, 0.0392, 0.0173, 0.036, 0.0371)), .Names = c("date", 
"value"), class = "data.frame", row.names = c(NA, -8L))


ddf
        date   value
1 2014-02-05  0.0379
2 2014-02-06 -0.0008
3 2014-02-07  0.0352
4 2014-02-12  0.0379
5 2014-02-14  0.0392
6 2014-02-17  0.0173
7 2014-02-18  0.0360
8 2014-02-19  0.0371


ddf$rolling_sd=0
for(i in 5:nrow(ddf)){
    ddf$rolling_sd[i]= sd(ddf$value[(i-4):i])
}
ddf
        date   value  rolling_sd
1 2014-02-05  0.0379 0.000000000
2 2014-02-06 -0.0008 0.000000000
3 2014-02-07  0.0352 0.000000000
4 2014-02-12  0.0379 0.000000000
5 2014-02-14  0.0392 0.017212408
6 2014-02-17  0.0173 0.017278108
7 2014-02-18  0.0360 0.008982038
8 2014-02-19  0.0371 0.009130991