我有一个时间序列数据框,看起来像
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天选择一次数据,然后计算可用数据的标准差。任何有关这方面的建议都将受到高度赞赏。
答案 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