Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

numbering by groups [duplicate]

Tags:

r

Suppose we have the following database:

ID  Shoot  hit
1     10    2
1      9    3
1      8    1
2     10    8
2      8    8
2     11   10
2      7    2
3      9    2
4      6    6
4      6    5
.
.

And I would like to have it with numbers assigned in each group, in this case per ID such as:

ID Shoot hit number.in.group
1   10     2    1
1    9     3    2
1    8     1    3
2   10     8    1
2    8     8    2 
2   11    10    3
2    7     2    4
3    9     2    1
4    6     6    1
4    6     5    2
    .
    .

I could do it easily using a loop. Something like these would work:

df$number.in.group = rep(1,nrow(df))

for(i in 2:nrow(df))
    if(df$ID[i]==df$ID[i-1]){
     df$number.in.group[i] = df$number.in.group[i-1] + 1 }  

My question is, is there any function or more elegant way of doing this other than using a loop?

like image 884
aatrujillob Avatar asked Nov 28 '22 11:11

aatrujillob


2 Answers

If you want a one-liner, something like

df$number.in.group = unlist(lapply(table(df$ID),seq.int))
like image 143
Simon Urbanek Avatar answered Nov 30 '22 02:11

Simon Urbanek


You could just use rle and sequence:

dat <- read.table(text = "ID  Shoot  hit
+ 1     10    2
+ 1      9    3
+ 1      8    1
+ 2     10    8
+ 2      8    8
+ 2     11   10
+ 2      7    2
+ 3      9    2
+ 4      6    6
+ 4      6    5",sep = "",header = TRUE)

> sequence(rle(dat$ID)$lengths)
 [1] 1 2 3 1 2 3 4 1 1 2

Indeed, I think sequence is intended for exactly this purpose.

like image 28
joran Avatar answered Nov 30 '22 02:11

joran