提问者:小点点

过滤掉具有有限数据的滚动平均值结果


我试图计算一个时间序列的滚动平均值。我对计算没有任何问题,但是,查看结果,在时间序列中的一些位置,滚动平均值是基于一个或两个被一长串缺失值包围的值。我希望滚动平均只发生在超过50%的数据在滚动平均的时间范围内执行的时候。如果可用数据少于50%,则该索引的结果应为< code>NaN。

我写了一些示例代码来希望演示我想要完成的任务。

#Create example data
set.seed(12)
dat1=runif(20,min=0,max=10)
dat2=dat1
ind=which(dat2 %in% sample(dat2,5))
#in this case ind=c(4, 7, 8, 13, 16)
dat2[ind]=NA

dat3=dat1
ind2=which(dat3 %in% sample(dat3,12))
#in this case ind2=c(2, 5, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18)
dat3[ind2]=NA

#create a time series
now <- Sys.time()
tseq <- seq(from = now, length.out = 20, by = "mins")

#data in zoo format
dat1=zoo(dat1,tseq)
dat2=zoo(dat2,tseq)
dat3=zoo(dat3,tseq)

#rolling mean using roll apply
dat1rollmean=rollapply(dat1,width=5,align='center',FUN=function(x) mean(x,na.rm=T))
dat2rollmean=rollapply(dat2,width=5,align='center',FUN=function(x) mean(x,na.rm=T))
dat3rollmean=rollapply(dat3,width=5,align='center',FUN=function(x) mean(x,na.rm=T))

#doesn't work
dat3newrollmean=rollmean(dat3,5)

#desired rolling mean result
dat2des=dat2rollmean
dat2des[4]=NaN

dat3des=dat3rollmean
dat3des[c(4:14)]=NaN

在本例中,dat1是一个完整的数据集,我的rollapply(宽度为5)函数运行良好,dat2和dat3有不同程度的缺失数据。在这种情况下,我希望我的结果用< code>NaN替换对少于2个数据点执行rollapply的任何点。这将是< code>dat2rollmean的索引4和< code>dat3rollmean的索引4-14。我该如何编写一个函数来查找这些数据不足的实例,并用< code>NaN替换得到的滚动平均结果?


共1个答案

匿名用户

使用下面定义的Mean

Mean <- function(x) if (sum(is.na(x)) < length(x) / 2) mean(x, na.rm = TRUE) else NaN

res1 <- rollapply(dat1, 5, Mean)
identical(res1, dat1rollmean)
## [1] TRUE

res2 <- rollapply(dat2, 5, Mean)
identical(res2, dat2des)
## [1] TRUE

res3 <- rollapply(dat3, 5, Mean)
identical(res3, dat3des)
## [1] TRUE