在数据框中创建一个计数器,该计数器根据值的变化进行重置[重复]

问题描述 投票:0回答:2

我有一个带有 ID 列和另一列(Base/Promo)编码 1 或 0 的 df。我想创建第三个新列,其中包含一个计数器,如果(Base/Promo)中的值为 0 则进行计数,并且如果 (Base/Promo) 中的值为 1,则重置为 0,并在值为 0 时重新开始计数。此外,每当 ID 更改时,计数器都应重置。这是一个可重现的 df 以及输出应该是什么样子的示例:

df <- data.frame(ID = c(rep("1", 6), rep("2", 6), 
rep("3", 6) rep("4", 6)), 
response=c(0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,1,1,0))             
df

期望的结果:

      ID     Base/Promo     counter
1     1         0           1
2     1         0           2
3     1         0           3
4     1         1           0
5     1         0           1
6     1         0           2
7     2         1           0
8     2         0           1
9     2         0           2
10    2         0           3
11    2         0           4
12    2         1           0
13    3         0           1
14    3         0           2
15    3         0           3
16    3         1           0
17    3         1           0
18    3         0           1
19    4         0           1
20    4         0           2
21    4         0           3
22    4         1           0
23    4         1           0
24    4         0           1

我尝试使用以下代码:

df <- df %>%
group_by(ID, idx = cumsum("Base/Promo" == 1L)) %>%
mutate(counter= row_number()) %>%
ungroup %>%
  select(-idx)

但这给了我以下结果:

      ID     Base/Promo     counter
1     1         0           1
2     1         0           2
3     1         0           3
4     1         1           1
5     1         0           2
6     1         0           3
7     2         1           1
8     2         0           2
9     2         0           3
10    2         0           4
11    2         0           5
12    2         1           1
13    3         0           2
14    3         0           3
15    3         0           4
16    3         1           1
17    3         1           1
18    3         0           2
19    4         0           1
20    4         0           2
21    4         0           3
22    4         1           1
23    4         1           1
24    4         0           2

我希望你能帮助解决这个问题,因为我不知道还能尝试什么。如果我忽略了解决我问题的 SO 条目,如果您能指出我那里,那就太好了。非常感谢!!!

r cumsum
2个回答
0
投票

我们可以根据组的

counter
值来调整
first
值 :

library(dplyr)

df %>%
  group_by(ID, grp = cumsum(response == 1L)) %>%
  mutate(counter = if(first(response) == 1L) row_number() - 1 
                   else row_number()) %>%
  ungroup() %>%
  dplyr::select(-grp)

# A tibble: 24 x 3
#   ID    response counter
#   <chr>    <dbl>   <dbl>
# 1 1            0       1
# 2 1            0       2
# 3 1            0       3
# 4 1            1       0
# 5 1            0       1
# 6 1            0       2
# 7 2            1       0
# 8 2            0       1
# 9 2            0       2
#10 2            0       3
# … with 14 more rows
     

0
投票

您可以使用 rle 生成序列并将结果与否定响应相乘。

df %>%
  group_by(ID) %>%
  mutate(x = with(rle(response), sequence(lengths)) * !response)

# A tibble: 24 x 3
# Groups:   ID [4]
   ID    response     x
   <chr>    <dbl> <int>
 1 1            0     1
 2 1            0     2
 3 1            0     3
 4 1            1     0
 5 1            0     1
 6 1            0     2
 7 2            1     0
 8 2            0     1
 9 2            0     2
10 2            0     3
# ... with 14 more rows
© www.soinside.com 2019 - 2024. All rights reserved.