web-dev-qa-db-fra.com

Comment modifier les niveaux d'une colonne de facteur dans un fichier data.table

Quelle est la bonne façon de changer les niveaux d’une colonne factor dans une colonne data.table _ (note: pas de trame de données)

  library(data.table)
  mydt <- data.table(id=1:6, value=as.factor(c("A", "A", "B", "B", "B", "C")), key="id")

  mydt[, levels(value)]
  [1] "A" "B" "C"

Je cherche quelque chose comme:

mydt[, levels(value) <- c("X", "Y", "Z")]

Mais bien sûr, la ligne ci-dessus ne fonctionne pas.

    # Actual               # Expected result
    > mydt                  > mydt
       id value                id value
    1:  1     A             1:  1     X
    2:  2     A             2:  2     X
    3:  3     B             3:  3     Y
    4:  4     B             4:  4     Y
    5:  5     B             5:  5     Y
    6:  6     C             6:  6     Z
46
Ricardo Saporta

Vous pouvez toujours les définir de manière traditionnelle:

levels(mydt$value) <- c(...)

Cela devrait être très rapide à moins que mydt soit très volumineux puisque cette syntaxe traditionnelle copie tout l'objet. Vous pouvez également jouer au jeu de décompactage et de refactoring ... mais personne n'aime ce jeu de toute façon.

Pour changer les niveaux par référence sans copie de mydt:

setattr(mydt$value,"levels",c(...))

mais assurez-vous d’affecter un vecteur de niveaux valide (tapez character de longueur suffisante), sinon vous obtiendrez un facteur non valide (levels<- vérifie et copie).

59
Justin

Je préférerais utiliser la méthode traditionnelle de réaffectation aux facteurs

> mydt$value # This we what we had originally
[1] A A B B B C
Levels: A B C
> levels(mydt$value) # just checking the levels
[1] "A" "B" "C"
**# Meat of the re-assignment**
> levels(mydt$value)[levels(mydt$value)=="A"] <- "X"
> levels(mydt$value)[levels(mydt$value)=="B"] <- "Y"
> levels(mydt$value)[levels(mydt$value)=="C"] <- "Z"
> levels(mydt$value)
[1] "X" "Y" "Z"
> mydt # This is what we wanted
   id value
1:  1     X
2:  2     X
3:  3     Y
4:  4     Y
5:  5     Y
6:  6     Z

Comme vous le remarquerez probablement, le viande de la réaffectation est très intuitif, il vérifie l'exacte level (utilisez grepl au cas où il y aurait un calcul flou, régulier expressions ou même)

levels(mydt$value)[levels(mydt$value)=="A"] <- "X" Vérifie explicitement la valeur dans le levels de la variable à l’étude, puis y réaffecte X (et ainsi de suite) - L’avantage, vous SAVEZ explicitement ce qui est étiqueté quoi.

Je trouve les niveaux de renommage comme ici levels(mydt$value) <- c("X","Y","Z") très non intuitive, puisqu'il assigne simplement X au 1er niveau, il VOIT dans les données (l'ordre est donc important) )

PPS: Si le nombre de niveaux est trop élevé, utilisez des constructions en boucle.

5
ekta

Vous pouvez également renommer et ajouter à vos niveaux en utilisant une approche associée, ce qui peut s'avérer très pratique, en particulier si vous créez un graphique qui nécessite des étiquettes plus informatives dans un ordre particulier (par opposition à la valeur par défaut):

f <- factor(c("a","b"))
levels(f) <- list(C = "C", D = "a", B = "b")

(modifié de ?levels)

3
Bryan Hanson