Dovresti usare i fattori. Sì, possono essere un dolore, ma la mia teoria è che il 90% del motivo per cui sono un dolore è perché in read.table
e read.csv
, l'argomento stringsAsFactors = TRUE
per impostazione predefinita (e la maggior parte degli utenti perde questa sottigliezza). Dico che sono utili perché i pacchetti di adattamento del modello come lme4 utilizzano fattori e fattori ordinati per adattare i modelli in modo differenziale e determinare il tipo di contrasti da utilizzare. E i pacchetti grafici li usano anche per raggruppare. ggplot
e la maggior parte delle funzioni di adattamento del modello obbliga i vettori di caratteri a fattori, quindi il risultato è lo stesso. Tuttavia, ti ritroverai con avvisi nel codice:
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
Messaggio di avviso: In model.matrix.default(mt, mf, contrasts)
:
variabile Species
convertita in un filefactor
Una cosa complicata è l'intera parte drop=TRUE
. Nei vettori questo funziona bene per rimuovere i livelli di fattori che non sono nei dati. Per esempio:
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
Tuttavia , con data.frame
s, il comportamento di [.data.frame()
è diverso: vedi questa email o ?"[.data.frame"
. Utilizzando drop=TRUE
il data.frame
s non funziona come ci si immagina:
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
Fortunatamente puoi eliminare facilmente i fattori droplevels()
per eliminare i livelli di fattore inutilizzati per un singolo fattore o per ogni fattore in a data.frame
(da R 2.12):
x <- subset(iris, Species == 'setosa')
levels(x$Species)
# [1] "setosa" "versicolor" "virginica"
x <- droplevels(x)
levels(x$Species)
# [1] "setosa"
Ecco come mantenere i livelli che hai selezionato per entrare nelle ggplot
leggende.
Internamente, factor
s sono numeri interi con un vettore di caratteri a livello di attributo (vedere attributes(iris$Species)
e class(attributes(iris$Species)$levels)
), che è pulito. Se dovessi cambiare il nome di un livello (e stavi usando stringhe di caratteri), questa sarebbe un'operazione molto meno efficiente. E cambio molto i nomi dei livelli, soprattutto per le ggplot
leggende. Se fingi fattori con vettori di caratteri, c'è il rischio che cambierai solo un elemento e crei accidentalmente un nuovo livello separato.