我想计算某个时间窗口内的移动平均值,而不是在时间序列的开头生成NA。例如,如果我将时间窗口设置为3,则2个第一个观察将具有NA。我想要的是第一次观察的时间窗口为1,第二次观察的时间窗口为2,然后是所有剩余观察的时间窗口。
我目前的代码:
#example data
x <- c(3,9,2,8,4,6,5,8)
#moving average with time window of length 3
(ma3 <- filter(x,rep(1/3,3),sides=1))
答案 0 :(得分:5)
我没有看到除暴力之外的其他方式:
使用rollapply
包中的zoo
代替filter
:
c(x[1], mean(x[1:2]), rollapply(x, width=3, FUN=mean))
答案 1 :(得分:3)
让我跳上rollapply
火车:
> rollapply(c(NA, NA, x), width=3, FUN=mean, na.rm=T)
[1] 3.000000 6.000000 4.666667 6.333333 4.666667 6.000000 5.000000 6.333333
预先设置两个= 3-1 NA
值并使用na.rm=T
具有延长时间序列但忽略计算均值的新值的效果。稍微困难但其他方面等效的语法
> rollapply(c(NA, NA, x), width=3, FUN=function(v) mean(v, na.rm=T))
感谢马修指出这一点。
答案 2 :(得分:2)
@thelatemail做得很好,但是代码中有一个错误(test[]
应该用函数内的x[]
替换)更重要的是他必须做同样的事情向量的结尾(如果你想要side = 2)。窗口大小也应该是向量中第i个元素的两倍+ 1(以及末尾的第i个元素)。
所以,这是最终版本:
movavg.grow = function(x,window) {
startma = sapply(1:(floor(window/2)),function(y) mean(x[1:((y-1)*2+1)]))
endma = sapply(1:(floor(window/2)),function(y) mean(x[(length(x)-((y-1)*2)):length(x)]))
endma = rev(endma)
c(startma,
filter(x,rep(1/window,window))[(floor(window/2):(length(x)- floor(window)/2)+1)],
endma)
}
对于测试,您想要的内容必须为1:10
x=1:10
> x=1:10
> x
[1] 1 2 3 4 5 6 7 8 9 10
> movavg.grow(x,5)
[1] 1 2 3 4 5 6 7 8 9 10
> movavg.grow(x,3)
[1] 1 2 3 4 5 6 7 8 9 10
答案 3 :(得分:1)
使用移动平均线的大小将0添加到序列的开头和结尾。这将阻止NA。
答案 4 :(得分:1)
基地R中的自定义功能可以帮助您:
movavg.grow <- function(x,window,sides) {
startma <- sapply(1:(window-1),function(y) mean(x[1:y]))
c(startma,filter(x,rep(1/window,window),sides=sides)[window:length(x)])
}
测试它:
> test <- c(3,9,2,8,4,6,5,8)
> movavg.grow(x=test,window=3,sides=1)
[1] 3.000000 6.000000 4.666667 6.333333 4.666667 6.000000 5.000000 6.333333
答案 5 :(得分:0)
您要询问的功能称为“部分”窗口,而AFAIK则已在动物园包装中提供。
数据。表中还有一个新的快速滚动平均值功能,该功能将在 1.12.0 中发布。
不幸的是,它不支持部分窗口,但是您可以通过以下方式使用该功能的“自适应”功能来实现所需的行为:
x = c(3,9,2,8,4,6,5,8)
window = 3
library(data.table)
n = c(seq.int(window), rep(window, length(x)-window))
frollmean(x, n, adaptive=TRUE)
#[1] 3.000000 6.000000 4.666667 6.333333 4.666667 6.000000 5.000000 6.333333
您可以在?froll
在线找到有关新功能的手动输入。