Una domanda che mi viene posta abbastanza di frequente da chi non è solito usare i modelli statistici è: «che cosa sono i fattori?». La prima volta che ho dovuto a rispondere a tale quesito, devo ammetterlo, mi sono trovato un po’ in difficoltà. Sembra assurdo, ma per chi si occupa di statistica inferenziale (a qualsiasi livello) il concetto è così tanto dato per scontato da rendere complicato trovare le parole giuste per descriverlo a chi non ha mai fatto statistica o non ha mai avuto a che fare con il disegno di un esperimento.
La cosa più difficile da spiagare è quale sia la differenza tra variabili di tipo carattere e variabili di tipo fattore. Infatti, quando i dati vengono importati in R, i caratteri – e solo i caratteri – vengono convertiti in “factor”. Ma che cosa cambia? Non avremmo potuto lasciare tutto com’era e lavorare con le variabili “character” invece che “factor”? Tanto, sempre di stringhe si tratta!
Invece no, non si tratta sempre di stringhe, e adesso proverò a spiegarvi perché.
La differenza tra caratteri e fattori
Il fattore è un tipo di dato che permette di etichettare un gruppo di osservazioni utilizzando delle categorie predefinite. Immaginiamo di aver registrato in una tabella alcuni dati relativi a sette personaggi Disney residenti a Paperopoli e dintorni:
Nome | Indirizzo | Genere |
Paperina | Vico II dei ciclamini, 2 | F |
Paperoga | Piazza C. Barks, 33 | M |
Nonna Papera | Viale degli uliveti, s.n. | F |
Gastone | Via della Dea Bendata, 1 | M |
Paperino | Via della marineria, 8 | M |
Brigitta | Via dei ciclamini, 21 | F |
Zio Paperone | Colle del deposito, s.n. | M |
Questa tabella di dati contiene tre variabili: il nome del personaggio, l’indirizzo di residenza e il sesso. In tutti e tre i casi, le osservazioni sono codificate attraverso dei caratteri, ma solo una di queste variabili potrà essere utilizzata come fattore: il genere. Il nome e l’indirizzo, infatti, rappresentano dei dati univoci e caratteristici di ogni singolo personaggio. Se dovessimo raggruppare i personaggi, di certo non potremo usare l’indirizzo come criterio di raggruppamento, visto che ogni personaggio abita in un luogo diverso, né tantomeno il nome, univoco per definizione. Il genere, al contrario, è una variabile che può assumere solo due valori (F: femmina, M: maschio) e consente di suddividere i personaggi in due gruppi, uno di tre unità (le femmine) e uno di quattro unità (i maschi).
La prima differenza tra il tipo fattore e il tipo carattere consiste quindi nel fatto che il fattore serve per raggruppare le unità sottoposte a osservazione, mentre la semplice variabile di tipo carattere no. Il fattore assume un numero limitato di modalità, dette livelli, che specificano il gruppo di appartenenza di un’unità/individuo.
La seconda differenza tra il tipo fattore e il tipo carattere è che i dati che andranno a rappresentare una variabile fattore non necessariamente devono essere registrati utilizzando dei caratteri. Nell’esempio dei personaggi Disney, per codificare il genere ho usato delle etichette, ovvero F e M, ma queste etichette sono state scelte esclusivamente a mia personalissima discrezione. Nessuno mi avrebbe impedito di scrivere per esteso “femmina” o “maschio” o utilizzare addirittura dei numeri, magari 1 per indicare le femmine e 0 i maschi. Sarebbe invece stato più complicato indicare l’indirizzo attraverso dei numeri e sicuramente i caratteri erano d’obbligo per specificare il nome del personaggio.
La gestione dei fattori in R
Il tipo fattore assume un senso e gioca un ruolo fondamentale quando si deve adattare un modello statistico. Si immagini di voler eseguire un confronto tra gruppi di individui, suddivisi sulla base di una qualche caratteristica. R deve sapere ogni individuo a quale gruppo appartiene, per cui in fase di analisi dei dati sarà necessario specificare una variabile (fattore, ovviamente) che indica al software a quale raggruppamento appartiene ogni unità sottoposta a misurazione.
Da questo indirizzo è possibile scaricare in formato csv il dataset descritto nella precedente tabella. Per importare i dati in R dobbiamo prima di tutto scaricarli in locale e quindi leggerli usando la funzione read.csv2, con l’accorgimento di impostare l’argomento stringsAsFactors come FALSE; saremo noi, in seguito all’importazione, a decidere cosa convertire in fattore e cosa no.
disney <- read.csv2("disney.csv", stringsAsFactors=FALSE) [/code] Visualizziamo la struttura del dataset: [code language="R"] > str(disney) 'data.frame': 7 obs. of 4 variables: $ Nome : chr "Paperina" "Paperoga" "Nonna Papera" "Gastone" ... $ Indirizzo: chr "Vico II dei ciclamini, 2" "Piazza C. Barks, 33" "Viale degli uliveti, s.n." "Via della Dea Bendata, 1" ... $ Genere : chr "F" "M" "F" "M" ... $ Sesso : int 1 0 1 0 0 1 0
Rispetto alla tabella, in questo dataset è presente un’ulteriore variabile, Sesso, che codifica il genere utilizzando dei numeri: 1 per le femmine e 0 per i maschi.
La funzione per ricodificare una variabile come fattore si chiama as.factor. Iniziamo con il ricodificare la variabile di tipo carattere Genere:
disney$Genere <- as.factor(disney$Genere) [/code] Vediamo quindi l'esito della ricodifica: [code language="R"] > str(disney$Genere) Factor w/ 2 levels "F","M": 1 2 1 2 2 1 2 > disney$Genere [1] F M F M M F M Levels: F M
Il comando str, che descrive la struttura della variabile, ci informa che Genere adesso è un fattore a due livelli: “F” e “M”. Anche quando visualizziamo tutti i valori contenuti nel vettore, di seguito alla sequenza di valori (alla voce Levels), R stampa l’elenco delle etichette che costituiscono i livelli dei fattori.
Soffermiamoci un attimo sull’esito dell’applicazione del comando str sulla variabile fattore. Di seguito all’elenco dei livelli, “F” e”M”, compare una sequenza di numeri: 1 2 1 2 2 1 2. R codifica i livelli di un fattore numerandoli; il numero 1 viene assegnato al primo livello, il numero 2 al secondo livello, il numero 3 al terzo livello, e così via.
La scelta dei numeri è strettamente legata all’ordine alfabetico delle etichette utilizzate per rappresentare i livelli. In ordine alfabetico, l’etichetta “F” viene prima dell’etichetta “M”, per cui a “F” sarà assegnato il numero 1 e a “M” il numero 2. Per questo motivo, trasformare una variabile di tipo fattore in una variabile di tipo numerico è un’operazione concessa in R:
> as.numeric(disney$Genere) [1] 1 2 1 2 2 1 2
Ovviamente, nell’operazione di conversione da tipo fattore a tipo numerico, le etichette “F” verranno rimpiazzate dal numero 1 (perché F è il primo livello) e le etichette “M” verranno rimpiazzate dal numero 2 (perché M è il secondo livello).
Proviamo ora a convertire in fattore la variabile numerica Sesso:
> disney$Sesso <- as.factor(disney$Sesso) > disney$Sesso [1] 1 0 1 0 0 1 0 Levels: 0 1
Nella variabile fattore Sesso, 0 (che codifica i maschi) è il primo livello, mentre 1 (che codifica le femmine) è il secondo livello. Questo accade semplicemente perché, nella sequenza numerica, 0 viene prima di 1. Ora, quindi, è la categoria “maschio” che costituisce il primo livello, mentre la categoria “femmina” il secondo.
Si noti che, nonostante i dati siano stati etichettati con dei numeri, sui fattori non è consentito applicare alcuna funzione matematica:
> mean(disney$Sesso) [1] NA Warning message: In mean.default(disney$Sesso) : argument is not numeric or logical: returning NA
Riconvertire il tipo fattore in tipo numerico
La rappresentazione numerica che R utilizza per codificare i fattori rischia di creare molta confusione. La categoria che noi abbiamo etichettato con 0 viene codificata da R con il numero 1, mentre la categoria che noi abbiamo etichettato con 1 viene codificata da R con il numero 2. Se volessimo riconvertire il fattore Sesso in una variabile numerica, rischieremmo di combinare un vero disastro. Questo è infatti l’esito della conversione:
> as.numeric(disney$Sesso) [1] 2 1 2 1 1 2 1
Nel riconvertire in formato numerico la variabile, R non utilizza le etichette che noi abbiamo attribuito ai livelli, ma la codifica numerica che lui ha dato ai livelli. Come fare allora?
La soluzione è semplice: per riconvertire una variabile fattore in tipo numerico, prima la si trasforma in carattere e solo succcessivamente le stringhe potranno essere convertite in numeri. Ovvero:
> disney$Sesso <- as.character(disney$Sesso) > disney$Sesso [1] "1" "0" "1" "0" "0" "1" "0" > disney$Sesso <- as.numeric(disney$Sesso) > disney$Sesso [1] 1 0 1 0 0 1 0
Oppure, in un unico comando:
disney$Sesso <- as.numeric(as.character(disney$Sesso)) [/code] Per ora concludiamo qui: direi che di roba da digerire ce n'è a sufficienza!
Ciao Davide,
Ottimo post!
Io mi son creato una funzioncina semplice semplice per convertire da fattore a numerico.
factonum = function(x){
x = as.numeric(as.character(x))
}
Ciao
Grazie Francesco! Tra non molto arriverà anche il seguito del post, con la gestione “avanzata” dei fattori.