使用 NA 值创建指数移动平均线时出错

问题描述 投票:0回答:1

我正在尝试创建指数移动平均线。然而,似乎没有一个函数能够以完全相同的方式处理

NA
值。所以我从某人那里找到了一个处理
NA
值的解决方案,但不是我想要的方式:

rollmeanEMA <- function(vec, len) {
  v_n <- !is.na(vec)
  c( vec[is.na(vec)],
     cumsum(vec[v_n][1:(len-1)]) / seq_along(vec[v_n][1:(len-1)]),
     EMA(vec[v_n], len)[len:length(vec[v_n])])
}

当我在向量的开头有

NA
时,它工作正常:

dados <- c(NA, 0, 0, 3, 0, 0, 0, 0, 0, 2, 0, 0)
> rollmeanEMA(dados, 8)
 [1]        NA 0.0000000 0.0000000 1.0000000
 [5] 0.7500000 0.6000000 0.5000000 0.4285714
 [9] 0.3750000 0.5781250 0.5058594 0.4426270

但是当我将

NA
放在另一个位置时,它的行为不正确,因为它将
NA
移动到向量的开头,而我希望它保持在原来的位置:

dados <- c(0, 0, 0, 3, 0, 0, 0, 0, 0, 2, 0, NA)
> rollmeanEMA(dados, 8)
 [1]        NA 0.0000000 0.0000000 0.0000000
 [5] 0.7500000 0.6000000 0.5000000 0.4285714
 [9] 0.3750000 0.3281250 0.5371094 0.4699707```

所以,我实际上希望代码与常规移动平均线完全相同,并忽略

NA
值。也就是说,如果数据是
c(0, 0, 0, 3, 0, 0, 0, NA, 0, 2, 0, 4)
,在与
NA
的线上,我希望它计算
c(0, 0, 0, 3, 0, 0, 0)
的指数移动平均值。 如果它与
4
在线,我希望它计算
c(4, 0, 2, 0)
的指数平均值,忽略
c(NA, 0, 0, 0, 3)
,从而使用时间窗口中的
8
值。

值得注意的是,我正在使用动态时间窗口,因此如果在我要计算平均值的行之前没有

7
先前的数据点,则
ma_len
(移动平均长度)将是之前存在的行数,即每组的
ma_len = c(1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, ...)

r data.table moving-average
1个回答
0
投票

评论太长了。

据我了解,您希望每次迭代选择八个(过去

x
值,并计算这些值的指数加权(移动)平均值(〜EMA)。

如果所选序列包含

NA
值,您希望忽略这些值并减少
n
(= "要平均的周期数。[...]") 动态 以匹配
 的长度所选
窗口中的NA值,请参阅
?TTR::EMA

您可以尝试一下

的变体
unrecommended = \(x, k) {
  # I use k instead of n
  y = rep(NA, length(x))
  for (i in seq_along(x)) 
    if (i > k) { 
      rw = na.omit(x[(i-k+1L):i]); l = length(rw)
      if(k >= l) y[[i]] = TTR::EMA(rw, k)[[k]] else y[[i]] = TTR::EMA(rw, l)[[l]] 
    }
  y
}

这给出了

> x = c(14.24, 13.82, 12.75, 12.92, 12.94, 13.00, 14.14, 16.28, 20.64, 17.64)
> lapply(c(2,4,6,8), \(k) unrecommended(x, k = k))
[[1]]
 [1]     NA     NA 13.285 12.835 12.930 12.970 13.570 15.210
 [9] 18.460 19.140

[[2]]
 [1]      NA      NA      NA      NA 13.1075 12.9025 13.2500
 [8] 14.0900 16.0150 17.1750

[[3]]
 [1]       NA       NA       NA       NA       NA       NA
 [7] 13.26167 13.67167 14.98667 15.77333

[[4]]
 [1]       NA       NA       NA       NA       NA       NA
 [7]       NA       NA 14.56125 15.03875

显然,这种方法是右对齐,您可以用类似于

@Waldi的
NA
的想法替换前导i < k
(由于
EMA2
而自然发生)。

我认为

unrecommended()
背后的做法是错误的。我建议改变方法。请至少查看这些来源

注意

© www.soinside.com 2019 - 2024. All rights reserved.