Cumulative count of each value

The dplyr way:

library(dplyr)

foo <- data.frame(id=c(1, 2, 3, 2, 2, 1, 2, 3))
foo <- foo %>% group_by(id) %>% mutate(count=row_number())
foo

# A tibble: 8 x 2
# Groups:   id [3]
     id count
  <dbl> <int>
1     1     1
2     2     1
3     3     1
4     2     2
5     2     3
6     1     2
7     2     4
8     3     2

That ends up grouped by id. If you want it not grouped, add %>% ungroup().


The ave function computes a function by group.

> id <- c(1,2,3,2,2,1,2,3)
> data.frame(id,count=ave(id==id, id, FUN=cumsum))
  id count
1  1     1
2  2     1
3  3     1
4  2     2
5  2     3
6  1     2
7  2     4
8  3     2

I use id==id to create a vector of all TRUE values, which get converted to numeric when passed to cumsum. You could replace id==id with rep(1,length(id)).


Here is a way to get the counts:

id <- c(1,2,3,2,2,1,2,3)

sapply(1:length(id),function(i)sum(id[i]==id[1:i]))

Which gives you:

[1] 1 1 1 2 3 2 4 2

For completeness, adding a data.table way:

library(data.table)

DT <- data.table(id = c(1, 2, 3, 2, 2, 1, 2, 3))

DT[, count := seq(.N), by = id][]

Output:

   id count
1:  1     1
2:  2     1
3:  3     1
4:  2     2
5:  2     3
6:  1     2
7:  2     4
8:  3     2