簡體   English   中英

基於向量的下一個值的條件cumsum

[英]Conditional cumsum based on the next value of a vector

我正在嘗試根據以下條件計算具有元素0,1,NA的向量的累積和:

1)只需計算NA值之間的cumsums

2)如果0在1之后,那么我想要cumsum + 1

Out是原始向量:

out[1:100]
  [1] NA NA NA NA  0  1  1 NA NA NA  1 NA  0 NA  0  1 NA NA  0 NA  0  1  0  0  0 NA  0  1  0  1  0  0  1  0  1  1  0  0  0  0
 [41]  1  0 NA  0  0 NA  1 NA  0  1 NA  0 NA  0  1  1 NA  1 NA  0  0  0  1  1 NA NA NA  0  0 NA  0  0  0  1  0 NA  1  0 NA  0
 [81]  1  1  0  1  1  0  1  0 NA  0  1  0  1  0 NA  0  1  0  0  1

我使用此代碼計算NA值之間的cumsums:

g <- cumsum(is.na(head(c(0, out), -1)))
out1 <- ave(out, g, FUN = cumsum)

我明白了

out1[1:100]
  [1] NA NA NA NA  0  1  2 NA NA NA  1 NA  0 NA  0  1 NA NA  0 NA  0  1  1  1  1 NA  0  1  1  2  2  2  3  3  4  5  5  5  5  5
 [41]  6  6 NA  0  0 NA  1 NA  0  1 NA  0 NA  0  1  2 NA  1 NA  0  0  0  1  2 NA NA NA  0  0 NA  0  0  0  1  1 NA  1  1 NA  0
 [81]  1  2  2  3  4  4  5  5 NA  0  1  1  2  2 NA  0  1  1  1  2

現在我只是有一個問題,我想得到cumsum + 1,如果1后跟一個零(這里只是第一個零)

例如

0 1 1 0 0 0 1 0 1 1 NA

憑借我現在擁有的功能,我會得到

0 1 2 2 2 2 3 3 4 5 NA,但我想要的是:

0 1 2 3 3 3 4 5 6 7 NA

有人可以幫忙嗎? 謝謝。

嘗試這個

out <- c(NA, NA, NA, NA, 0, 1, 1, NA, NA, NA, 1, NA, 0, NA, 0, 1, NA, 
    NA, 0, NA, 0, 1, 0, 0, 0, NA, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 
    0, 0, 0, 1, 0, NA, 0, 0, NA, 1, NA, 0, 1, NA, 0, NA, 0, 1, 1, 
    NA, 1, NA, 0, 0, 0, 1, 1, NA, NA, NA, 0, 0, NA, 0, 0, 0, 1, 0, 
    NA, 1, 0, NA, 0, 1, 1, 0, 1, 1, 0, 1, 0, NA, 0, 1, 0, 1, 0, NA, 
    0, 1, 0, 0, 1, NA, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, NA)

as.numeric(unlist(lapply(split(out, cumsum(is.na(out))),
    function(x) {
        if (length(x) == 1) return(x)
        idx <- which(x[-length(x)] == 1 & x[-1] == 0)
        res <- cumsum(x[-1])
        for (i in seq_along(idx)) {
            if (i == length(idx))
                res[seq(idx[i], length(res))] <- res[seq(idx[i], length(res))] + i
            else
                res[seq(idx[i], idx[i + 1] - 1)] <- res[seq(idx[i], idx[i + 1] - 1)] + i
        }
        c(NA, res)
    }
)))
#  [1] NA NA NA NA  0  1  2 NA NA NA  1 NA  0 NA  0  1 NA NA  0 NA  0  1  2  2  2
# [26] NA  0  1  2  3  4  4  5  6  7  8  9  9  9  9 10 11 NA  0  0 NA  1 NA  0  1
# [51] NA  0 NA  0  1  2 NA  1 NA  0  0  0  1  2 NA NA NA  0  0 NA  0  0  0  1  2
# [76] NA  1  2 NA  0  1  2  3  4  5  6  7  8 NA  0  1  2  3  4 NA  0  1  2  2  3
#[101] NA  0  1  2  3  3  3  4  5  6  7 NA

或者,您可以計算out1保留現有方法(使用ave ),然后通過識別需要添加的序列來“添加”缺失的位

na.pos <- which(is.na(out))
idx <- which(out[-length(out)] == 1 & out[-1] == 0)
idx2 <- which(is.na(out[-1]) | (out[-length(out)] == 1 & out[-1] == 0))

beg <- idx + 1
end <- idx2[findInterval(idx, idx2) + 1]
to.add <- as.numeric(unlist(sapply(rle(findInterval(idx, na.pos))$lengths, seq, from = 1)))

for(i in seq_along(beg))
    out1[seq(beg[i], end[i])] <- out1[seq(beg[i], end[i])] + to.add[i]

應該有一個更簡單的方法,但你可以試試這個:

temp1 <- out
temp1[is.na(temp1)] <- 0

temp2 <- (temp1[2:length(temp1)] == 0) * (temp1[1:length(temp1)-1]==1)
temp2 <- c(0, temp2)

out1 <- cumsum(temp1+temp2)- cummax(cumsum((temp1+temp2))*is.na(out))
out1[is.na(out)] <- NA

rm(temp1, temp2)

out1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM