如何计算连续累加和?

3
假设我有一个 tibble。
id  year    X   
1   2001   False      
1   2002   TRUE       
1   2003   TRUE       
1   2004   False      
1   2005   False      
1   2006   TRUE       
1   2007   TRUE
1   2008   TRUE

如何计算变量 X 的连续累积和?
id  year    X     cumN
1   2001   False     0
1   2002   TRUE      1
1   2003   TRUE      2
1   2004   False     0
1   2005   False     0
1   2006   TRUE      1
1   2007   TRUE      2
1   2008   TRUE      3

谢谢!

dt <- tibble(id = rep(1,8),
             year = 2001:2008,
             X = c(FALSE, TRUE, TRUE, FALSE, FALSE, TRUE,TRUE,TRUE))
3个回答

2
你可以使用rleMap功能将数值与长度相匹配,将所有的False替换为0。
dt$cumN <- unlist(with(dt, Map(\(x,y) replace(seq(x), !y, 0), rle(X)$lengths, rle(X)$values)))

     id  year X      cumN
  <dbl> <int> <lgl> <dbl>
1     1  2001 FALSE     0
2     1  2002 TRUE      1
3     1  2003 TRUE      2
4     1  2004 FALSE     0
5     1  2005 FALSE     0
6     1  2006 TRUE      1
7     1  2007 TRUE      2
8     1  2008 TRUE      3


2

有两种可能的方法来解决您的问题(一种基于dplyrdata.table包的混合使用,另一种仅基于data.table):

方法1
library(data.table)

setDT(dt)[, cumN := cumsum(X), fifelse(X, y<-rleid(X), y+1L)]

      id  year      X  cumN
   <num> <int> <lgcl> <int>
1:     1  2001  FALSE     0
2:     1  2002   TRUE     1
3:     1  2003   TRUE     2
4:     1  2004  FALSE     0
5:     1  2005  FALSE     0
6:     1  2006   TRUE     1
7:     1  2007   TRUE     2
8:     1  2008   TRUE     3
way 2
library(dplyr)

dt %>%
  group_by(tem = if_else(X, y<-data.table::rleid(X), y+1L)) %>%
  mutate(cumN=cumsum(X)) %>%
  ungroup() %>%
  select(!tem)

# A tibble: 8 x 4
     id  year X      cumN
  <dbl> <int> <lgl> <int>
1     1  2001 FALSE     0
2     1  2002 TRUE      1
3     1  2003 TRUE      2
4     1  2004 FALSE     0
5     1  2005 FALSE     0
6     1  2006 TRUE      1
7     1  2007 TRUE      2
8     1  2008 TRUE      3

另一个可能性是:rowid(rleid(X))* X - Henrik

1

可能有一种特殊的dplyr方法来完成这个任务,但我认为谦虚的for循环可能更简单:

dt$cumsum = 0

for (i in 1:nrow(dt)) {
    condition = dt$X[[i]]
    if (condition & i > 1) {
        dt$cumsum[[i]] = dt$cumsum[[i - 1]] + 1
    } else {
        dt$cumsum[[i]] = 0
    }
}

> dt
# A tibble: 8 × 4
     id  year X     cumsum
  <dbl> <int> <lgl>  <dbl>
1     1  2001 FALSE      0
2     1  2002 TRUE       1
3     1  2003 TRUE       2
4     1  2004 FALSE      0
5     1  2005 FALSE      0
6     1  2006 TRUE       1
7     1  2007 TRUE       2
8     1  2008 TRUE       3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接