如何在 R 中重置为 0 时执行 cumsum?
How to perform cumsum with reset at 0 in R?
我有一个table,我想获得一个组内的累计总和(按ID),但是如果在一个组内的任何一点计数器为0,则累计计数应该重置,然后再次启动从 1 开始的累计计数。
ID Counter Cumulative
A 1 1
A 0 0
A 1 1
A 1 2
B 1 1
B 0 0
B 1 1
创建一个临时组列,每次遇到 0 时创建一个新组。
library(dplyr)
df %>%
group_by(ID, grp = cumsum(Counter == 0)) %>%
mutate(Cumulative = cumsum(Counter)) %>%
ungroup() %>%
select(-grp) -> result
result
# ID Counter Cumulative
# <chr> <int> <int>
#1 A 1 1
#2 A 0 0
#3 A 1 1
#4 A 1 2
#5 B 1 1
#6 B 0 0
#7 B 1 1
相同的逻辑可以在 base R 和 data.table
中实现为:
df$Cumulative <- with(df, ave(Counter, ID, cumsum(Counter == 0), FUN = cumsum))
library(data.table)
setDT(df)[, Cumulative := cumsum(Counter), .(ID, cumsum(Counter == 0))]
数据
df <- structure(list(ID = c("A", "A", "A", "A", "B", "B", "B"), Counter = c(1L,
0L, 1L, 1L, 1L, 0L, 1L)), class = "data.frame", row.names = c(NA, -7L))
另一种方法可以是
df %>% group_by(ID) %>%
mutate(cs = accumulate(Counter, ~ifelse(.y == 0, .y, .x + .y)))
根据亲爱的@Ronak 在他的评论中提供的数据检查它
df <- structure(list(ID = c("A", "A", "A", "A", "A", "B", "B", "B"), Counter = c(1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L)), class = "data.frame", row.names = c(NA, -8L))
df %>% group_by(ID) %>%
mutate(cs = accumulate(Counter, ~ifelse(.y == 0, .y, .x + .y)))
# A tibble: 8 x 3
# Groups: ID [2]
ID Counter cs
<chr> <int> <int>
1 A 1 1
2 A 0 0
3 A 1 1
4 A 1 2
5 A 1 3
6 B 1 1
7 B 0 0
8 B 1 1
我有一个table,我想获得一个组内的累计总和(按ID),但是如果在一个组内的任何一点计数器为0,则累计计数应该重置,然后再次启动从 1 开始的累计计数。
ID Counter Cumulative
A 1 1
A 0 0
A 1 1
A 1 2
B 1 1
B 0 0
B 1 1
创建一个临时组列,每次遇到 0 时创建一个新组。
library(dplyr)
df %>%
group_by(ID, grp = cumsum(Counter == 0)) %>%
mutate(Cumulative = cumsum(Counter)) %>%
ungroup() %>%
select(-grp) -> result
result
# ID Counter Cumulative
# <chr> <int> <int>
#1 A 1 1
#2 A 0 0
#3 A 1 1
#4 A 1 2
#5 B 1 1
#6 B 0 0
#7 B 1 1
相同的逻辑可以在 base R 和 data.table
中实现为:
df$Cumulative <- with(df, ave(Counter, ID, cumsum(Counter == 0), FUN = cumsum))
library(data.table)
setDT(df)[, Cumulative := cumsum(Counter), .(ID, cumsum(Counter == 0))]
数据
df <- structure(list(ID = c("A", "A", "A", "A", "B", "B", "B"), Counter = c(1L,
0L, 1L, 1L, 1L, 0L, 1L)), class = "data.frame", row.names = c(NA, -7L))
另一种方法可以是
df %>% group_by(ID) %>%
mutate(cs = accumulate(Counter, ~ifelse(.y == 0, .y, .x + .y)))
根据亲爱的@Ronak 在他的评论中提供的数据检查它
df <- structure(list(ID = c("A", "A", "A", "A", "A", "B", "B", "B"), Counter = c(1L, 0L, 1L, 1L, 1L, 1L, 0L, 1L)), class = "data.frame", row.names = c(NA, -8L))
df %>% group_by(ID) %>%
mutate(cs = accumulate(Counter, ~ifelse(.y == 0, .y, .x + .y)))
# A tibble: 8 x 3
# Groups: ID [2]
ID Counter cs
<chr> <int> <int>
1 A 1 1
2 A 0 0
3 A 1 1
4 A 1 2
5 A 1 3
6 B 1 1
7 B 0 0
8 B 1 1