web-dev-qa-db-fra.com

Compter le nombre d'enregistrements et générer un numéro de ligne dans chaque groupe dans une table de données.

J'ai les données suivantes.

set.seed(1)
DT <- data.table(VAL = sample(c(1, 2, 3), 10, replace = TRUE))
    VAL
 1:   1
 2:   2
 3:   2
 4:   3
 5:   1
 6:   3
 7:   3
 8:   2
 9:   2
10:   1

À l'intérieur chaque nombre dans VAL Je veux:

  1. Compter le nombre d'enregistrements/lignes
  2. Créez un index de ligne (compteur) de première, deuxième, troisième occurrence, etc.

A la fin je veux le résultat

    VAL COUNT IDX
 1:   1     3   1
 2:   2     4   1
 3:   2     4   2
 4:   3     3   1
 5:   1     3   2
 6:   3     3   2
 7:   3     3   3
 8:   2     4   3
 9:   2     4   4
10:   1     3   3

où "COUNT" est le nombre d'enregistrements/lignes pour chaque "VAL" et "IDX" est l'index de ligne dans chaque "VAL".

J'ai essayé de travailler avec which et length en utilisant .I:

 dt[, list(COUNT = length(VAL == VAL[.I]), 
             IDX = which(which(VAL == VAL[.I]) == .I))]

mais cela ne fonctionne pas comme .I fait référence à un vecteur avec l'index, donc je suppose que l'on doit utiliser .I[]. Bien qu'à l'intérieur .I[] Je suis à nouveau confronté au problème, que je n'ai pas l'index de ligne et je sais (d'après la lecture de data.table FAQ et suivre les articles ici) que le bouclage à travers les lignes doit être évité si possible.

Alors, quel est le data.table façon?

54
Simon Z.

En utilisant .N...

DT[ , `:=`( COUNT = .N , IDX = 1:.N ) , by = VAL ]
#    VAL COUNT IDX
# 1:   1     3   1
# 2:   2     4   1
# 3:   2     4   2
# 4:   3     3   1
# 5:   1     3   2
# 6:   3     3   2
# 7:   3     3   3
# 8:   2     4   3
# 9:   2     4   4
#10:   1     3   3

.N est le nombre d'enregistrements dans chaque groupe, les groupes étant définis par "VAL".

88
Simon O'Hanlon