移动平均线功能问题

时间:2016-07-26 23:56:39

标签: r moving-average

我有两个向量。每天我想添加一行以使数据集更大一行:

day1 <- c(0,0,8,10,4,5,3,5,6,10,7,11,9,7,10,13,8,7,5,4)
day2 <- c(0,0,8,10,4,5,3,5,6,10,7,11,9,7,10,13,8,7,5,4,0)

我有两个函数分别作为累积均值和滚动均值。两者都给出了平均值的滞后值。

cumroll <- function(x) {
    if(length(x)<=1) {x}
    else {
        x <- head(x, -1)
        c(head(x,1), cumsum(x) / seq_along(x))
    }
}

rollmean <- function(x, n) {if (length(x) <= n) cumroll(x) else rollapply(x,list(-seq(n)), mean, fill = cumroll(x))}

我希望使用此代码在两个数据集上进行20的滚动平均值:

day1_avg <- ave(day1, FUN = function(x) rollmean(x, 20))
day2_avg <- ave(day2, FUN = function(x) rollmean(x, 20))

当我运行day1_avg时,它会按照我的预期行动,因为只有20次观察,所以使用了cumroll。但是当我用21次观察运行day2_avg时,第21次观察之前的每个值都会自动给出0而不是累积值。

结果如下,我想要的day2_avg输出:

day2     day1_avg     day2_avg    DESIRED
0        0            0           0
0        0            0           0
8        0            0           0
10       2.666667     0           2.666667
4        4.5          0           4.5
5        4.4          0           4.4
3        4.5          0           4.5
5        4.285714     0           4.285714
6        4.375        0           4.375
10       4.555556     0           4.555556
7        5.1          0           5.1
11       5.272727     0           5.272727
9        5.75         0           5.75
7        6            0           6
10       6.071429     0           6.071429
13       6.333333     0           6.333333
8        6.75         0           6.75
7        6.823529     0           6.823529
5        6.833333     0           6.833333
4        6.736842     0           6.736842
0                     6.6         6.6  

我需要以某种方式修改函数,以确保在第n次观察rollmean之后,cumroll值保持不变。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

更改您的rollmean

rollmean <- function(x, n) {if (length(x) <= n) tmp<- cumroll(x)
else {tmp<-rollapply(x,list(-seq(n)), mean, fill = cumroll(x))
tmp[1:n]<-cumroll(x[1:n])
}
tmp}

你会得到:

> tail(cbind(day1,day1_avg,day2,day2_avg))
      day1 day1_avg day2 day2_avg
[17,]    8 6.750000    8 6.750000
[18,]    7 6.823529    7 6.823529
[19,]    5 6.833333    5 6.833333
[20,]    4 6.736842    4 6.736842
[21,]    0 0.000000    0 6.600000
[22,]    0 0.000000    1 6.600000