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
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).
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.
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
)