我想在数据中间获得“ MovingAverage”的数据,如下所示。
date <- seq.Date(as.Date("2018-07-02"),as.Date("2018-07-14"),by = "days")
A <- c(100,110,120,130,140,NA,NA,150,160,170,180,190,200)
B <- c(200,220,240,260,280,NA,NA,300,320,340,360,380,400)
C <- c(150,160,170,180,190,200,210,NA,NA,220,230,240,250)
dataset <- data.frame(A,B,C)
dataset <- as.xts(dataset, order.by = date)
如果我像下面那样使用rollapply
来获得3天的MovingAverage ...
y <- rollapply(dataset, width = 3, function(x) mean(x, na.rm = TRUE ))
这不是我想要的。
例如,在"2018-07-09"
处的A的MovingAverage中,结果为(NA+NA+150)/1 = 150
。但是我想得到(130+140+150)/3 = 140
。
我该怎么做?
答案 0 :(得分:2)
我假设您希望NA保留为NA,否则要取最近3个非NA的平均值。
1)一次取5个元素,如果最后一个元素为NA,则返回NA。否则,请删除NA,取最后3的平均值。请注意,这确实意味着前4行将为NA。
mean_bus <- function(x) if (is.na(tail(x, 1))) NA else mean(tail(na.omit(x), 3))
y1 <- rollapplyr(dataset, width = 5, mean_bus)
2)一种替代方法是采用最后3个非NA,然后在输入为NA的所有位置都用NA覆盖它。
mean_omit <- function(x) mean(tail(na.omit(x), 3))
y <- rollapplyr(dataset, 5, mean_omit)
y2 <- replace(y, is.na(dataset), NA)
all.equal(y1, y2)
## [1] TRUE
3)如果您希望在前4行中填充部分值,请转换为zoo并使用rollapplyr.zoo
的partial =参数。 mean_bus
来自(1)。
y3 <- as.xts(rollapplyr(as.zoo(dataset), 5, mean_bus, partial = TRUE))
答案 1 :(得分:0)
您可以在计算移动平均值(MA)之前删除每个系列中的NA。
或者您使用更大的窗口,并仅保留MA的最后三个值。
y <- rollapply(dataset, width = 5,
function(x) {mean(tail(x[ !is.na(x) ], 3))})