【问题标题】:Get multiple/grouped sums for a vector with values separated by NA's获取值由 NA 分隔的向量的多个/分组总和
【发布时间】:2019-01-16 17:37:37
【问题描述】:

我的previous question 有更新:

c(123, 4525, 4365, 234, 674, NA, NA, NA, NA, NA, NA, NA, 
  24, 347, 457, 3246, 234, 5, 346, NA, NA, NA, NA, NA, NA) # [... and so on]

有什么方法可以让我得到由我的 NA 分隔的每个值的总和?值和 NA 在向量上的长度都是分开的,这就是我看到问题的地方……

Ronak Shah 的回答非常有帮助,但仍然存在问题: 我有一些值,它们的总和等于 0。 但这对我来说是一个重要的信息!
因此,如果我使用new[new != 0],我会将它们切断,并且我不知道最终哪些总和属于哪个值包。

【问题讨论】:

  • 如果上一个问题已解决,但您有新的相关问题,请将新问题自包含。上一个问题的链接会有所帮助,但即使不阅读另一个问题,也应该可以回答这个问题。
  • 对不起,我是这个网站的新手。

标签: r vector sum


【解决方案1】:

我们可以通过aggregaterleid 做到这一点

library(data.table)
i1 <- is.na(x)
aggregate(cbind(val = x[!i1])~ cbind(grp = rleid(i1)[!i1]), FUN = sum)
#  grp  val
#1   1 9921
#2   3 4659
#3   5 5289
#4   7    0
#5   9    0

【讨论】:

    【解决方案2】:

    这可能有点令人费解。逻辑是合理的,但很可能有一种方法可以简化它。

    c(123, 4525, 4365, 234, 674, NA, NA, NA, NA, NA, NA, NA, 24, 347, 457, 3246,
    234, 5, 346, NA, NA, NA, NA, NA, NA, 45, 778, 986, 3345, 135, NA, NA, NA, NA,
    0, 0, NA, NA, 99, -2, -97, NA, NA) -> x
    
    isna <- !is.na(x)
    ix <- c(0, diff(isna)) + isna
    ix[ix == 1] <- 0
    ix <- cumsum(ix) + 1
    
    ix <- ix * as.integer(isna)
    
    sapply(split(x, ix)[-1], sum)
    #    1    2    3    4    5 
    # 9921 4659 5289    0    0 
    

    发生的情况是,我通过各种逻辑和算术运算创建了一个索引,该索引具有与每次运行非 nas 相对应的唯一编号。然后将向量沿该索引拆分,并对每个结果元素求和。


    从 Moody 那里获得灵感,这是一个基于 rle() 的解决方案

    notnaruns <- function(x) {
        notna <- !is.na(x)
        notnarl <- rle(isna)$lengths
        repruns <- rep(1:length(notnarl), notnarl) + 1
        repruns * notna * 0.5
    }
    
    tapply(x, notnaruns(x), sum)[-1]
    #    1    2    3    4    5 
    # 9921 4659 5289    0    0 
    

    【讨论】:

    • 我必须承认我理解了你脚本的 50%。但它第一次尝试所以非常感谢!!!
    • 我也做了自己的混音 :) : tapply( x[!is.na(x)], cumsum(diff(c(0,is.na(x)))==-1)[!is.na(x)] , sum)
    • 如果我们确定 x 不以 NA 开头,则可能只是 tapply( x, cumsum(diff(c(0,is.na(x)))==-1) , sum, na.rm= TRUE)
    【解决方案3】:

    你可以使用data.table::rleid

    library(data.table)
    tapply(x[!is.na(x)], rleid(is.na(x))[!is.na(x)], sum)
    #    1    3    5    7    9 
    # 9921 4659 5289    0    0 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多