非工作日滚动移动平均线

时间:2018-08-02 08:18:37

标签: r finance moving-average

我想在数据中间获得“ 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

我该怎么做?

2 个答案:

答案 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))})