2016-10-11 6 views
0

Используя функцию rollsum в zoo, я вижу NAs вместо того, что я ожидал бы быть действительными значениями. rollapply использованием sum работ, как ожидалось, но rollsum не:rollsum производящий неожиданный NA

library(zoo) 
x <- c(1,2,3,NA,NA,4,5,6) 
x 
[1] 1 2 3 NA NA 4 5 6 
rollapply(x, 3, FUN=sum, fill=NA) 
[1] NA 6 NA NA NA NA 15 NA 
rollsum(x, 3, fill=NA) 
[1] NA 6 NA NA NA NA NA NA 

Я что-то упустил или это ошибка в оптимизации rollsum использует?

+0

'? Zoo :: rollsum' утверждает, что' rollmean' не обрабатывает 'NA' - возможно, из-за использования 'cumsum'. Кажется, что и для 'rollsum' тоже. –

+0

Имеет смысл. Странно, что он производит неверный результат вместо ошибки. – andrew

+1

Возможно, «RcppRoll :: roll_sum» может быть альтернативой вам – Rentrop

ответ

1

По умолчанию методы rollmean и rollsum не обрабатывают входы, содержащие NA. В таких случаях вместо этого используйте rollapply.

0

rollsum определяется в rollmean.R следующим образом:

rollsum <- function(x, k, fill = if (na.pad) NA, na.pad = FALSE, 
    align = c("center", "left", "right"), ...) { 
    UseMethod("rollsum") 
} 

где метод:

rollsum.zoo <- function(x, k, fill = if (na.pad) NA, na.pad = FALSE, 
    align = c("center", "left", "right"), ...) { 

    if (!missing(na.pad)) warning("na.pad is deprecated. Use fill.") 

    align <- match.arg(align) 

    if (length(dim(x)) == 2) { 
     # merge is the only zoo specific part of this method 

     out <- do.call("merge", c(lapply(1:NCOL(x), function(i) { 
     rollsum(x[, i, drop = TRUE], k, fill = fill, align = align, ...) 
     }), all = FALSE)) 
     if (ncol(x) == 1) dim(out) <- c(length(out), 1) 
     colnames(out) <- colnames(x) 
     return(out) 
    } 

    n <- length(x) 
    stopifnot(k <= n) 

    ix <- switch(align, 
     "left" = { 1:(n-k+1) }, 
     "center" = { floor((1+k)/2):ceiling(n-k/2) }, 
     "right" = { k:n }) 

    xu <- unclass(x) 
    y <- xu[k:n] - xu[c(1, seq_len(n-k))] # difference from previous 
    y[1] <- sum(xu[1:k])  # find the first 
    # sum precomputed differences 
    rval <- cumsum(y) 

    x[ix] <- rval 
    na.fill(x, fill = fill, ix) 

} 

Если вы пошагово функции вы увидите, что это на самом деле не из-за cumsum, что в результате оценивает NA, где вы ожидали бы 15 (или, по крайней мере, это не первая причина этого), если бы вы исправили текущую проблему, возможно, cumsum также вызовет проблему, я не знаю). Это линия

y <- xu[k:n] - xu[c(1, seq_len(n-k))].

rollsum является новой функцией в пакете zoo и еще не обрабатывает NA, поэтому я предлагаю остановиться с rollapply.