R语言 按组重新启动计数器条件[重复]

qjp7pelc  于 2023-01-28  发布在  其他
关注(0)|答案(1)|浏览(143)
    • 此问题在此处已有答案**:

Create counter within consecutive runs of certain values(6个答案)
5天前关闭。
我有以下数据集:

id = c("A","A","A","A","A","B", "B", "B", "B")
result = c(1,1,0,1,1,0,1,0,1)
my_data = data.frame(id, result)
    • 对于每个唯一的ID,我想创建一个"计数器变量":**
  • 如果第一结果值为1,则计数器= 1,否则为0
  • 当结果= 1时,每次增加1
  • 当结果= 0时变为0
  • 保持0,直到遇到第一个结果= 1
  • 每次结果= 1时重新开始增加1
  • 当遇到下一个唯一ID时,如果result = 1,则计数器初始化回1,否则为0

我想最终的结果应该是这样的:

id result counter
1  A      1       1
2  A      1       2
3  A      0       0
4  A      1       1
5  A      1       2
6  B      0       0
7  B      1       1
8  B      0       0
9  B      1       1

我有这两个代码,我正在尝试使用:

# creates counter by treating entire dataset as a single ID
 my_data$counter =   unlist(lapply(split(my_data$results, c(0, cumsum(abs(diff(!my_data$results == 1))))), function(x) (x[1] == 1) * seq(length(x))))

# creates counter by taking into consideration ID's
my_data$counter = ave(my_data$results, my_data$id, FUN = function(x){ tmp<-cumsum(x);tmp-cummax((!x)*tmp)})

但是我不确定如何正确地解释它们。例如,我感兴趣的是学习如何编写一个通用函数来在一般条件下完成此任务-例如,如果result = AAA,则计数器重新启动为0,如果result = BBB,则计数器+1,如果result = CCC,则计数器+2,如果result = DDD,则计数器-1。
有人能教我怎么做吗?
谢谢!

k0pti3hp

k0pti3hp1#

我们可以使用rleid创建分组列,然后按"id"和"result"的rleid进行分组

library(dplyr)
library(data.table)
my_data %>% 
  group_by(id) %>%
  mutate(grp = rleid(result)) %>% 
  group_by(grp, .add = TRUE) %>%
  mutate(counter = row_number() * result)%>%
  ungroup %>% 
  select(-grp)
  • 输出
# A tibble: 9 × 3
  id    result counter
  <chr>  <dbl>   <dbl>
1 A          1       1
2 A          1       2
3 A          0       0
4 A          1       1
5 A          1       2
6 B          0       0
7 B          1       1
8 B          0       0
9 B          1       1

或者使用data.table

library(data.table)
setDT(my_data)[, counter := seq_len(.N) * result, .(id, rleid(result))]
  • 输出
> my_data
   id result counter
1:  A      1       1
2:  A      1       2
3:  A      0       0
4:  A      1       1
5:  A      1       2
6:  B      0       0
7:  B      1       1
8:  B      0       0
9:  B      1       1

相关问题