I am attempting to create an exponential moving average similar to the simple moving average like:
dt_STGE_res_artigo_semana[, SMA8 := round(frollmean(qtd_ref,
n = ma_len,
align = 'right',
na.rm = T,
hasNA = T,
adaptive = T), 2),
by = .(cod_edicao_adonix_real)]
However, it seems there isn’t a function that handles NA values exactly the same way. So I found a solution here that deals with NA values, but not in the way I want:
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])])
}
When I have NA at the beginning of the vector, it works fine:
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
but when I have NA in another position, it behaves incorrectly because it moves the NA to the beginning of the vector, and I want it to remain where it is:
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```
So, I actually wanted the code to do exactly the
same as in a regular moving average and
to ignore the NA values. That is, if the
data is c(0, 0, 0, 3, 0, 0, 0, NA, 0, 2, 0, 4),
on the line with NA, I want it to calculate the
exponential moving average of 0, 0, 0, 3, 0, 0, 0.
If it's on the line with 4, I want it to calculate the
exponential average of 4, 0, 2, 0, ignoring NA, 0, 0, 0, 3,
thus using 9 values from the time window.
It's worth noting that I'm working with a
dynamic time window, so if there aren't 7
previous data points before the line where
I want to calculate the average, the ma_len
(moving average length) will be the number
of lines that exist before it, i.e.,
ma_len = 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, etc.,
for each group.