Vous devez utiliser des facteurs. Oui, ils peuvent être une douleur, mais ma théorie est que 90% de la raison pour laquelle ils sont une douleur est parce que dans read.table
et read.csv
, l'argument stringsAsFactors = TRUE
par défaut (et la plupart des utilisateurs manquent cette subtilité). Je dis qu'ils sont utiles parce que les packages d'ajustement de modèle comme lme4 utilisent des facteurs et des facteurs ordonnés pour ajuster différemment les modèles et déterminer le type de contrastes à utiliser. Et les packages graphiques les utilisent également pour les regrouper. ggplot
et la plupart des fonctions d'ajustement de modèle contraignent les vecteurs de caractères à des facteurs, de sorte que le résultat est le même. Cependant, vous vous retrouvez avec des avertissements dans votre code:
lm(Petal.Length ~ -1 + Species, data=iris)
# Call:
# lm(formula = Petal.Length ~ -1 + Species, data = iris)
# Coefficients:
# Speciessetosa Speciesversicolor Speciesvirginica
# 1.462 4.260 5.552
iris.alt <- iris
iris.alt$Species <- as.character(iris.alt$Species)
lm(Petal.Length ~ -1 + Species, data=iris.alt)
# Call:
# lm(formula = Petal.Length ~ -1 + Species, data = iris.alt)
# Coefficients:
# Speciessetosa Speciesversicolor Speciesvirginica
# 1.462 4.260 5.552
Message d'avertissement: Dans model.matrix.default(mt, mf, contrasts)
:
variable Species
convertie enfactor
Une chose délicate est le tout drop=TRUE
. Dans les vecteurs, cela fonctionne bien pour supprimer les niveaux de facteurs qui ne sont pas dans les données. Par exemple:
s <- iris$Species
s[s == 'setosa', drop=TRUE]
# [1] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [11] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [21] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [31] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [41] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# Levels: setosa
s[s == 'setosa', drop=FALSE]
# [1] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [11] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [21] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [31] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [41] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# Levels: setosa versicolor virginica
Cependant , avec data.frame
s, le comportement de [.data.frame()
est différent: voir cet e-mail ou ?"[.data.frame"
. Utiliser drop=TRUE
on data.frame
s ne fonctionne pas comme vous l'imaginez:
x <- subset(iris, Species == 'setosa', drop=TRUE) # susbetting with [ behaves the same way
x$Species
# [1] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [11] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [21] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [31] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# [41] setosa setosa setosa setosa setosa setosa setosa setosa setosa setosa
# Levels: setosa versicolor virginica
Heureusement, vous pouvez facilement supprimer des facteurs avec droplevels()
pour supprimer les niveaux de facteurs inutilisés pour un facteur individuel ou pour chaque facteur dans a data.frame
(depuis R 2.12):
x <- subset(iris, Species == 'setosa')
levels(x$Species)
# [1] "setosa" "versicolor" "virginica"
x <- droplevels(x)
levels(x$Species)
# [1] "setosa"
Voici comment éviter que les niveaux que vous avez sélectionnés ne figurent dans les ggplot
légendes.
En interne, les factor
s sont des entiers avec un vecteur de caractère au niveau de l'attribut (voir attributes(iris$Species)
et class(attributes(iris$Species)$levels)
), qui est propre. Si vous deviez changer un nom de niveau (et que vous utilisiez des chaînes de caractères), ce serait une opération beaucoup moins efficace. Et je change beaucoup de noms de niveau, surtout pour les ggplot
légendes. Si vous simulez des facteurs avec des vecteurs de caractères, vous risquez de ne modifier qu'un seul élément et de créer accidentellement un nouveau niveau distinct.