Vous devriez utiliser des facteurs. Oui, ils peuvent être pénibles, mais ma théorie est que 90% de la raison pour laquelle ils sont pénibles est qu'en read.table
y read.csv
l'argument stringsAsFactors = TRUE
par défaut (et la plupart des utilisateurs passent à côté de cette subtilité). Je dis qu'ils sont utiles car les paquets d'ajustement de modèles comme lme4 utilisent les facteurs et les facteurs ordonnés pour ajuster les modèles de manière différentielle et déterminer le type de contrastes à utiliser. Et les paquets graphiques les utilisent également pour effectuer des regroupements. ggplot
et la plupart des fonctions d'ajustement de modèles transforment les vecteurs de caractères en facteurs, le résultat est donc 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
Warning message:
In model.matrix.default(mt, mf, contrasts) :
variable 'Species' converted to a factor
>
Une chose délicate est l'ensemble drop=TRUE
bit. Dans les vecteurs, cela fonctionne bien pour supprimer les niveaux des 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 les cadres de données, le comportement de [.data.frame()
est différent : voir cet e-mail o ?[.data.frame
(entre guillemets, ce que StackOverflow ne me laisse pas faire). En utilisant drop=TRUE
sur les cadres de données 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 faire tomber les facteurs facilement avec :
> x <- subset(iris, Species == 'setosa', drop=TRUE)
> levels(x$Species)
[1] "setosa" "versicolor" "virginica"
> x$Species <- factor(x$Species)
> levels(x$Species)
[1] "setosa"
ou :
> x$Species <- x$Species[drop=TRUE]
> levels(x$Species)
[1] "setosa"
C'est la façon d'éviter que les niveaux que vous avez sélectionnés n'apparaissent dans les légendes de ggplot.
En interne, les facteurs sont des entiers avec un vecteur de caractères de niveau d'attribut (voir attributes(iris$Species)
y class(attributes(iris$Species)$levels)
), ce qui est propre. Si vous deviez changer le nom d'un niveau (et que vous utilisiez des chaînes de caractères), ce serait un problème de type beaucoup opération moins efficace. Et je change souvent les noms des niveaux, surtout pour les légendes de ggplot. Si vous simulez des facteurs avec des vecteurs de caractères, vous risquez de modifier un seul élément et de créer accidentellement un nouveau niveau distinct.