Confusione tra i livelli dei fattori e le etichette dei fattori


106

Sembra esserci una differenza tra i livelli e le etichette di un fattore in R. Fino ad ora, ho sempre pensato che i livelli fossero il nome "reale" dei livelli dei fattori e le etichette fossero i nomi usati per l'output (come tabelle e grafici) . Ovviamente, questo non è il caso, come mostra il seguente esempio:

df <- data.frame(v=c(1,2,3),f=c('a','b','c'))
str(df)
'data.frame':   3 obs. of  2 variables:
 $ v: num  1 2 3
 $ f: Factor w/ 3 levels "a","b","c": 1 2 3

df$f <- factor(df$f, levels=c('a','b','c'),
  labels=c('Treatment A: XYZ','Treatment B: YZX','Treatment C: ZYX'))
levels(df$f)
[1] "Treatment A: XYZ" "Treatment B: YZX" "Treatment C: ZYX"

Pensavo che i livelli ('a', 'b', 'c') potessero in qualche modo essere ancora accessibili durante lo script, ma questo non funziona:

> df$f=='a'
[1] FALSE FALSE FALSE

Ma questo fa:

> df$f=='Treatment A: XYZ' 
[1]  TRUE FALSE FALSE

Quindi, la mia domanda si compone di due parti:

  • Qual è la differenza tra livelli ed etichette?

  • È possibile avere nomi diversi per i livelli di fattore per lo scripting e l'output?

Background: per script più lunghi, lo scripting con livelli di fattore brevi sembra essere molto più semplice. Tuttavia, per report e grafici, questi livelli di fattore brevi potrebbero non essere adeguati e dovrebbero essere sostituiti con nomi più precisi.

Risposte:


131

Molto breve: i livelli sono l'input, le etichette sono l'output nella factor()funzione. Un fattore ha solo un levelattributo, che è impostato labelsdall'argomento nella factor()funzione. Questo è diverso dal concetto di etichette in pacchetti statistici come SPSS e può creare confusione all'inizio.

Cosa fai in questa riga di codice

df$f <- factor(df$f, levels=c('a','b','c'),
  labels=c('Treatment A: XYZ','Treatment B: YZX','Treatment C: ZYX'))

sta dicendo a R che esiste un vettore df$f

  • che vuoi trasformare in un fattore,
  • in cui i diversi livelli sono codificati come a, be c
  • e per i quali desideri che i livelli siano etichettati come Trattamento A ecc.

La funzione fattore cercherà i valori a, bec, li convertirà in classi di fattori numerici e aggiungerà i valori dell'etichetta levelall'attributo del fattore. Questo attributo viene utilizzato per convertire i valori numerici interni nelle etichette corrette. Ma come vedi, non ci sono labelattributi.

> df <- data.frame(v=c(1,2,3),f=c('a','b','c'))    
> attributes(df$f)
$levels
[1] "a" "b" "c"

$class
[1] "factor"

> df$f <- factor(df$f, levels=c('a','b','c'),
+   labels=c('Treatment A: XYZ','Treatment B: YZX','Treatment C: ZYX'))    
> attributes(df$f)
$levels
[1] "Treatment A: XYZ" "Treatment B: YZX" "Treatment C: ZYX"

$class
[1] "factor"

1
Grazie per la risposta rapida! Immagino di capire lo scopo dei livelli e delle etichette ora. Forse qualche suggerimento per rendere l'output umanamente più leggibile senza modificare manualmente i nomi delle tabelle e le leggende della trama?
donodarazao

6
Spesso trasformavo i livelli subito prima di tracciare / creare etichette, ad es. Mantieni i livelli come "a", "b", "c" durante la manipolazione, quindi uso i livelli (f) <- paste ("Trattamento", toupper (livelli ( f)), sep = "") [o qualcosa del genere] durante la stampa. Oppure crea un fattore parallelo f_pretty che ti porti dietro e che usi solo per l'output ...
Ben Bolker

Ho pensato a entrambi, ma entrambi i metodi hanno degli svantaggi. Il primo potrebbe diventare noioso quando si traccia un numero enorme di grafici e il secondo potrebbe diventare noioso quando nello scripting è coinvolta una grande quantità di aggregazione dei dati. Ma a quanto pare non c'è modo di evitarlo facilmente, quindi seguirò i tuoi suggerimenti. :)
donodarazao

@ 42- Non sono sicuro di cosa intendi con "valori numerici". Se intendi i valori interni del fattore, allora è esattamente quello che ho detto sopra. Da qui la menzione di valori numerici interni . Se si specifica l' levelsargomento, si forniscono i valori nell'input che devono essere abbinati labelsall'argomento. R mantiene le etichette (come attributo levels, e c'è confusione) e memorizza internamente i codici interi. Questi codici interi non hanno nulla a che fare con i valori originali, qualunque essi fossero. Penso che tu mi abbia frainteso.
Joris Meys

Scuse. Ciò che hai scritto è stato anche la mia comprensione, e ora che sto rileggendo la tua domanda, non riesco a vedere dove pensavo avessi detto diversamente. Eliminerò il mio commento perché aggiunge meno di niente.
IRTFM

17

Ho scritto un pacchetto "lfactors" che ti consente di fare riferimento a livelli o etichette.

# packages
install.packages("lfactors")
require(lfactors)

flips <- lfactor(c(0,1,1,0,0,1), levels=0:1, labels=c("Tails", "Heads"))
# Tails can now be referred to as, "Tails" or 0
# These two lines return the same result
flips == "Tails"
#[1]  TRUE FALSE FALSE  TRUE  TRUE FALSE
flips == 0 
#[1]  TRUE FALSE FALSE  TRUE  TRUE FALSE

Notare che un fattore l richiede che i livelli siano numerici in modo che non possano essere confusi con le etichette.


3
questo è un bel pacchetto e grazie per averci scritto (e scritto). Sembra il tipo di funzionalità che dovrebbe essere nativo dei fattori R: bello vedere un pacchetto che fornisce questo tipo di mappatura delle coppie nome-valore con controlli di equivalenza incorporati.
Soren
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.