考虑以下命名向量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
的累计和。许多R函数都有一个参数na.rm
,它在计算之前删除了NA
个元素。 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
值的情况下,有哪些更好的方法可以返回累积金额?
答案 0 :(得分:27)
您可以在以下行中执行此操作:
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
或者,类似地:
library(dplyr)
cumsum(coalesce(x, 0)) + x*0
# a b c d e f g h
# 1 3 3 NA 7 NA NA 13
答案 1 :(得分:15)
你想要这样的东西:
x2 <- x
x2[!is.na(x)] <- cumsum(x2[!is.na(x)])
x2
[edit]或者,根据上述评论的建议,您可以将NA更改为0&#39; s -
miss <- is.na(x)
x[miss] <- 0
cs <- cumsum(x)
cs[miss] <- NA
# cs is the requested cumsum
答案 2 :(得分:8)
这是我从这个问题的答案中得出的一个函数。以为我会分享它,因为它似乎到目前为止运作良好。它会在忽略FUNC
的同时计算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
绝对没什么新鲜的,但也许对某人有用。
答案 3 :(得分:6)
这是一个老问题,但是tidyr
提供了一个新的解决方案。
基于将NA
替换为零的想法。
require(tidyr)
cumsum(replace_na(x, 0))
a b c d e f g h
1 3 3 3 7 7 7 13