Calculate cumsum() while ignoring NA values

后端 未结 4 1555
醉话见心
醉话见心 2020-11-27 20:49

Consider the following named vector 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条回答
  • 2020-11-27 21:23

    Do you want something like this:

    x2 <- x
    x2[!is.na(x)] <- cumsum(x2[!is.na(x)])
    
    x2
    

    [edit] Alternatively, as suggested by a comment above, you can change NA's to 0's -

    miss <- is.na(x)
    x[miss] <- 0
    cs <- cumsum(x)
    cs[miss] <- NA
    # cs is the requested cumsum
    
    0 讨论(0)
  • 2020-11-27 21:24

    Here's a function I came up from the answers to this question. Thought I'd share it, since it seems to work well so far. It calculates the cumulative FUNC of x while ignoring NA. FUNC can be any one of sum(), prod(), min(), or max(), and x is a numeric vector.

    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 
    

    Definitely nothing new, but maybe useful to someone.

    0 讨论(0)
  • 2020-11-27 21:29

    It's an old question but tidyr gives a new solution. Based on the idea of replacing NA with zero.

    require(tidyr)
    
    cumsum(replace_na(x, 0))
    
     a  b  c  d  e  f  g  h 
     1  3  3  3  7  7  7 13 
    
    0 讨论(0)
  • 2020-11-27 21:33

    You can do this in one line with:

    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
    

    Or, similarly:

    library(dplyr)
    cumsum(coalesce(x, 0)) + x*0
    #  a  b  c  d  e  f  g  h 
    #  1  3  3 NA  7 NA NA 13 
    
    0 讨论(0)
提交回复
热议问题