R 基于行值中的条件创建计数器

R 基于行值中的条件创建计数器,r,dplyr,R,Dplyr,我想创建一个计数器来计算数字的出现次数。 例如,假设我们有这样的数据 df <- data.frame(ID = c(rep(rep(seq(1:2),each=2),times=2)),gr=rep(c("A"),each=8)) ID gr 1 1 A 2 1 A 3 2 A 4 2 A 5 1 A 6 1 A 7 2 A 8 2 A 我试过这个 library(dplyr) df%>% group_by(gr)%>% mu

我想创建一个计数器来计算数字的出现次数。 例如,假设我们有这样的数据

df <- data.frame(ID = c(rep(rep(seq(1:2),each=2),times=2)),gr=rep(c("A"),each=8))

  ID gr
1  1  A
2  1  A
3  2  A
4  2  A
5  1  A
6  1  A
7  2  A
8  2  A
我试过这个

library(dplyr)

df%>%
  group_by(gr)%>%
  mutate(counter=cumsum(ID==2))
但它似乎甚至不接近理想的输出


我们怎样才能做到这一点呢?

有很多方法可以做到这一点

df <- data.frame(ID = c(rep(rep(seq(1:2),each=2),times=4)), gr= "A")
带有dplyr的选项:

输出:

# A tibble: 9 x 3
# Groups:   gr [1]
     ID     gr    id
  <dbl> <fctr> <dbl>
1     1      A     1
2     1      A     1
3     2      A     1
4     2      A     1
5     1      A     2
6     1      A     2
7     2      A     2
8     2      A     2
9     1      A     3
变异:df%>%groupbygr%>%mutategroup=cumsumc0,diffID==2<0+1L
group <- rep(NA, length(df$ID))
group[1] <- 1

for (i in 2:length(df$ID)) {
  if (df$ID[i] >= df$ID[i-1]) {
    group[i] <- group[i-1]
  } else {
    group[i] <- group[i-1] + 1
  }
}

df$group <- group
df

   ID gr group
1   1  A     1
2   1  A     1
3   2  A     1
4   2  A     1
5   1  A     2
6   1  A     2
7   2  A     2
8   2  A     2
9   1  A     3
10  1  A     3
11  2  A     3
12  2  A     3
13  1  A     4
14  1  A     4
15  2  A     4
16  2  A     4
library(dplyr)

findIncrSeq <- function(x) {
  group <- rep(NA, length(x))
  group[1] <- 1

  for (i in 2:length(x)) {
    if (x[i] >= x[i-1]) {
      group[i] <- group[i-1]
    } else {
      group[i] <- group[i-1] + 1
    }
  }
  group
}

df %>%
  group_by(gr) %>%
  mutate(counter = findIncrSeq(ID))

# A tibble: 16 x 4
# Groups:   gr [1]
      ID     gr group counter
   <int> <fctr> <dbl>   <dbl>
 1     1      A     1       1
 2     1      A     1       1
 3     2      A     1       1
 4     2      A     1       1
 5     1      A     2       2
 6     1      A     2       2
 7     2      A     2       2
 8     2      A     2       2
 9     1      A     3       3
10     1      A     3       3
11     2      A     3       3
12     2      A     3       3
13     1      A     4       4
14     1      A     4       4
15     2      A     4       4
16     2      A     4       4
# added one more row to your example
df <- data.frame(ID = c(rep(rep(seq(1:2),each=2),times=2),1),gr=rep(c("A"),each=9))

library(dplyr)
df %>% 
  group_by(gr) %>%
  mutate(id=cumsum(c(0,diff(df$ID)) & lag(df$ID==2))+1)
# A tibble: 9 x 3
# Groups:   gr [1]
     ID     gr    id
  <dbl> <fctr> <dbl>
1     1      A     1
2     1      A     1
3     2      A     1
4     2      A     1
5     1      A     2
6     1      A     2
7     2      A     2
8     2      A     2
9     1      A     3