考虑以下命名向量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
Run Code Online (Sandbox Code Playgroud)
我想计算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
Run Code Online (Sandbox Code Playgroud)
但这似乎过多了,并且制作了许多新的作业/副本.我相信有更好的方法.
在有效忽略 价值的同时,有哪些更好的方法可以返回累积金额NA ?
jos*_*ber 31
您可以在一行中执行以下操作:
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
Run Code Online (Sandbox Code Playgroud)
或者,类似地:
library(dplyr)
cumsum(coalesce(x, 0)) + x*0
# a b c d e f g h
# 1 3 3 NA 7 NA NA 13
Run Code Online (Sandbox Code Playgroud)
leb*_*nok 16
你想要这样的东西:
x2 <- x
x2[!is.na(x)] <- cumsum(x2[!is.na(x)])
x2
Run Code Online (Sandbox Code Playgroud)
[编辑]或者,正如上面的评论所建议的那样,你可以将NA改为0 -
miss <- is.na(x)
x[miss] <- 0
cs <- cumsum(x)
cs[miss] <- NA
# cs is the requested cumsum
Run Code Online (Sandbox Code Playgroud)
Ric*_*ven 10
这是我从这个问题的答案中得出的一个函数.以为我会分享它,因为它似乎到目前为止运作良好.它计算累积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
Run Code Online (Sandbox Code Playgroud)
绝对没什么新鲜的,但也许对某人有用.
DJV*_*DJV 10
这是一个老问题,但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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16556 次 |
| 最近记录: |