Вычислять cumsum() при игнорировании значений NA
Рассмотрим следующий именованный вектор x
.
( x <- setNames(c(1, 2, 0, NA, 4, NA, NA, 6), letters[1:8]) )
# a b c d e f g h
# 1 2 0 NA 4 NA NA 6
Я хотел бы вычислить суммарную сумму x
, игнорируя значения NA
. Поскольку аргумент na.rm
для cumsum()
отсутствует, это немного сложно.
Я могу сделать это таким образом.
y <- setNames(numeric(length(x)), names(x))
z <- cumsum(na.omit(x))
y[names(y) %in% names(z)] <- z
y[!names(y) %in% names(z)] <- x[is.na(x)]
y
# a b c d e f g h
# 1 3 3 NA 7 NA NA 13
Но это кажется чрезмерным и делает много новых заданий/копий. Я уверен, что есть лучший способ.
Какие лучшие методы возвращают кумулятивную сумму при эффективном игнорировании значений NA
?
Ответы
Ответ 1
Вы хотите что-то вроде этого:
x2 <- x
x2[!is.na(x)] <- cumsum(x2[!is.na(x)])
x2
[edit] Альтернативно, как было предложено выше, вы можете изменить NA на 0 -
miss <- is.na(x)
x[miss] <- 0
cs <- cumsum(x)
cs[miss] <- NA
# cs is the requested cumsum
Ответ 2
Вы можете сделать это в одной строке:
cumsum(ifelse(is.na(x), 0, x)) + x*0
# a b c d e f g h
# 1 3 3 NA 7 NA NA 13
Ответ 3
Вот функция, которую я выбрал из ответов на этот вопрос. Думал, что я поделюсь этим, так как пока все хорошо. Он вычисляет кумулятивный FUNC
of x
, игнорируя NA
. FUNC
может быть любым из sum()
, prod()
, min()
или max()
, а x
является числовым вектором.
cumSkipNA <- function(x, FUNC)
{
d <- deparse(substitute(FUNC))
funs <- c("max", "min", "prod", "sum")
stopifnot(is.vector(x), is.numeric(x), d %in% funs)
FUNC <- match.fun(paste0("cum", d))
x[!is.na(x)] <- FUNC(x[!is.na(x)])
x
}
set.seed(1)
x <- sample(15, 10, TRUE)
x[c(2,7,5)] <- NA
x
# [1] 4 NA 9 14 NA 14 NA 10 10 1
cumSkipNA(x, sum)
# [1] 4 NA 13 27 NA 41 NA 51 61 62
cumSkipNA(x, prod)
# [1] 4 NA 36 504 NA 7056 NA
# [8] 70560 705600 705600
cumSkipNA(x, min)
# [1] 4 NA 4 4 NA 4 NA 4 4 1
cumSkipNA(x, max)
# [1] 4 NA 9 14 NA 14 NA 14 14 14
Определенно ничего нового, но, возможно, полезного для кого-то.