Créer un compteur d'identifiants
lundi 1 mars 2010 :: R :: Lien permanent
Si on a le data frame suivant :
id type 10002 "7" 10061 "1" 10061 "1" 10061 "4" 10065 "7" 10114 "1" 10114 "1" 10114 "4" 10136 "7" 10136 "2" 10136 "2"
Et qu'on veut obtenir ceci :
id type counter 10002 "7" 1 10061 "1" 1 10061 "1" 2 10061 "4" 3 10065 "7" 1 10114 "1" 1 10114 "1" 2 10114 "4" 3 10136 "7" 1 10136 "2" 2 10136 "2" 3
Avant toutes chose il faut ordonner le data frame selon la variable id :
df <- df[order(df$id),]
On peut utiliser la méthode suivante, mais qui est très lente :
df$count <- unlist(tapply(df$id, df$id, order))
On peut également utiliser la fonction table, c'est plus rapide :
df$count <- unlist(lapply(table(df$id), function(x){1:x}))
Mais le plus rapide est de passer par la fonction lre :
df$count <- unlist(lapply(rle(as.vector(df$id))$lengths,function(x){1:x})))
Comparaison des temps d'exécution des trois méthodes :
R> system.time(unlist(tapply(tmp$ident, tmp$ident, order)))
utilisateur système écoulé
4.196 0.000 4.840
R> system.time(unlist(lapply(table(tmp$ident),function(x){1:x})))
utilisateur système écoulé
0.028 0.000 0.033
R> system.time(unlist(lapply(rle(as.vector(tmp$ident))$lengths,function(x){1:x})))
utilisateur système écoulé
0.012 0.000 0.018
Fonctions rapides fournies par spacedman sur #R.


Commentaires
bonjour, merci de ces programmes comparés et merci également pour le package Rgrs et l'introduction à R qui m'a permis de faire mes premiers pas dans ce logiciel. Le tout est parfaitement clair et j'y reviens souvent. J'ai deux questions
1) j'ai compris, sans doute à tort, que votre intention était de compter le nb de chaque type par id. Or, id= 10114, par exemple, présente à deux reprises le type 1, compté une fois (pourquoi pas, en une seule ligne, deux fois le type 1 ?)
2) dans la suite de votre compteur, comment, à présent et sur la base de votre exemple, serait-il possible d'obtenir un tableau dont les lignes seraient les ID (UNIQUES) + 7 colonnes (type 1 à type 7) décomptant pour chaque ID les valeurs prises par chaque type au total (comme le résultat de la table (id,type) mais avec 0 partout si aucun type) ? l'objectif est de merger ensuite avec une autre table par l'id.
Par exemple, l'id =10114, prendrait les valeurs suivantes dans chacune des sept colonnes : 2,0,0,3,0,0,0.
Quoi qu'il en soit, merci encore de votre travail.