R crear ID dentro de un grupo

Tengo el siguiente conjunto de datos:

df<-structure(list(IDFAM = c("2010 7599 2996 1", "2010 7599 3071 1", "2010 7599 3071 1", "2010 7599 3660 1", "2010 7599 4736 1", "2010 7599 6235 1", "2010 7599 6299 1", "2010 7599 9903 1", "2010 7599 11013 1", "2010 7599 11778 1", "2010 7599 11778 1", "2010 7599 12248 1", "2010 7599 13127 1", "2010 7599 14261 1", "2010 7599 16280 1", "2010 7599 16280 1", "2010 7599 16280 1", "2010 7599 16280 1", "2010 7599 16280 1", "2010 7599 17382 1"), AGED = c(45L, 47L, 24L, 46L, 46L, 44L, 43L, 43L, 43L, 16L, 43L, 46L, 44L, 47L, 43L, 16L, 20L, 18L, 18L, 43L)), .Names = c("IDFAM", "AGED"), row.names = c("5614", "5748", "5753", "6864", "8894", "11761", "11884", "18738", "20896", "22351", "22353", "23267", "24939", "27072", "30946", "30947", "30949", "30950", "30952", "33034"), class = "data.frame") 

Me gustaría asignar una ID a cada observación que tenga el mismo valor de IDFAM que va de 1 a n, donde n es el número de observaciones con el mismo valor de IDFAM . Esto daría como resultado la siguiente tabla:

 IDFAM AGED ID 2010 7599 2996 1 45 1 2010 7599 3071 1 47 1 2010 7599 3071 1 24 2 2010 7599 3660 1 46 1 2010 7599 4736 1 46 1 2010 7599 6235 1 44 1 2010 7599 6299 1 43 1 2010 7599 9903 1 43 1 2010 7599 11013 1 43 1 2010 7599 11778 1 16 1 2010 7599 11778 1 43 2 2010 7599 12248 1 46 1 2010 7599 13127 1 44 1 2010 7599 14261 1 47 1 2010 7599 16280 1 43 1 2010 7599 16280 1 16 2 2010 7599 16280 1 20 3 2010 7599 16280 1 18 4 2010 7599 16280 1 18 5 2010 7599 17382 1 43 1 

Cómo puedo hacer esto ? Gracias.

Hay varias formas.

En la base R, usa ave :

 with(df, ave(rep(1, nrow(df)), IDFAM, FUN = seq_along)) # [1] 1 1 2 1 1 1 1 1 1 1 2 1 1 1 1 2 3 4 5 1 

Con el paquete “data.table”, use la sequence(.N) :

 library(data.table) DT <- as.data.table(df) DT[, ID := sequence(.N), by = IDFAM] 

Con el paquete "dplyr", intente:

 df %>% group_by(IDFAM) %>% mutate(count = sequence(n())) 

o (según lo recomendado por Hadley en los comentarios):

 df %>% group_by(IDFAM) %>% mutate(count = row_number(IDFAM)) 

Actualizar

Como esto parece ser algo que se solicita con relativa frecuencia, esta función se ha agregado como una función ( getanID ) en mi paquete "splitstackshape". Se basa en el enfoque "data.table" anterior.

 library(splitstackshape) getanID(df, id.vars = "IDFAM") # IDFAM AGED .id # 1: 2010 7599 2996 1 45 1 # 2: 2010 7599 3071 1 47 1 # 3: 2010 7599 3071 1 24 2 # 4: 2010 7599 3660 1 46 1 # 5: 2010 7599 4736 1 46 1 # 6: 2010 7599 6235 1 44 1 # 7: 2010 7599 6299 1 43 1 # 8: 2010 7599 9903 1 43 1 # 9: 2010 7599 11013 1 43 1 # 10: 2010 7599 11778 1 16 1 # 11: 2010 7599 11778 1 43 2 # 12: 2010 7599 12248 1 46 1 # 13: 2010 7599 13127 1 44 1 # 14: 2010 7599 14261 1 47 1 # 15: 2010 7599 16280 1 43 1 # 16: 2010 7599 16280 1 16 2 # 17: 2010 7599 16280 1 20 3 # 18: 2010 7599 16280 1 18 4 # 19: 2010 7599 16280 1 18 5 # 20: 2010 7599 17382 1 43 1 

Con dplyr 0.5 puede usar la función group_indices . Aunque no es compatible con mutate , el siguiente enfoque es sencillo:

 df$id <- df %>% group_indices(IDFAM)