L’analisi esplorativa dei dati (AED, o Exploratory Data Analysis – EDA) ha lo scopo di mettere in luce aspetti interessanti e pattern caratteristici di un insieme di dati, ricorrendo a riassunti numerici e rappresentazioni grafiche, senza ricorrere a ipotesi formali sui dati.
Alcuni concetti chiave:
Esempio: se la popolazione sono i 218 comuni del Friuli Venezia Giulia, ogni comune è un’unità statistica, e variabili come numero di abitanti o superficie sono caratteri rilevati su di essi.
I dati possono essere raccolti per scopi diversi:
Le variabili si classificano in:
Variabile
├── Qualitativa (categoriale)
│ ├── Sconnessa (nominale): es. mezzo di trasporto
│ └── Dicotomica: solo 2 modalità (es. sì/no)
│ └── Ordinale: es. titolo di studio
└── Quantitativa (numerica)
├── Discreta: es. numero di figli
└── Continua: es. peso, reddito
Nota in R: le variabili qualitative vengono gestite come fattori (
factor). È importante trasformarle esplicitamente, perché molte funzioni R si comportano diversamente a seconda del tipo.
AutoBiIl dataset AutoBi (package insuranceData)
contiene dati su sinistri automobilistici. Carichiamolo e ispezioniamone
la struttura.
# install.packages("insuranceData") # eseguire se non installato
library(insuranceData)
data("AutoBi")
str(AutoBi)#> 'data.frame': 1340 obs. of 8 variables:
#> $ CASENUM : int 5 13 66 71 96 97 120 136 152 155 ...
#> $ ATTORNEY: int 1 2 2 1 2 1 1 1 2 2 ...
#> $ CLMSEX : int 1 2 1 1 1 2 1 2 2 1 ...
#> $ MARITAL : int NA 2 2 1 4 1 2 2 2 2 ...
#> $ CLMINSUR: int 2 1 2 2 2 2 2 2 2 2 ...
#> $ SEATBELT: int 1 1 1 2 1 1 1 1 1 1 ...
#> $ CLMAGE : int 50 28 5 32 30 35 19 34 61 NA ...
#> $ LOSS : num 34.94 10.892 0.33 11.037 0.138 ...
#> CASENUM ATTORNEY CLMSEX MARITAL CLMINSUR SEATBELT CLMAGE LOSS
#> 1 5 1 1 NA 2 1 50 34.940
#> 2 13 2 2 2 1 1 28 10.892
#> 3 66 2 1 2 2 1 5 0.330
#> 4 71 1 1 1 2 2 32 11.037
#> 5 96 2 1 4 2 1 30 0.138
#> 6 97 1 2 1 2 1 35 0.309
Le variabili presenti sono:
| Variabile | Descrizione | Tipo teorico |
|---|---|---|
CASENUM |
Numero del caso | Identificativo |
ATTORNEY |
Rappresentato da avvocato (1=sì, 2=no) | Qualitativa sconnessa |
CLMSEX |
Sesso del richiedente (1=M, 2=F) | Qualitativa sconnessa |
MARITAL |
Stato civile (1=married, …, 4=divorced) | Qualitativa sconnessa |
CLMINSUR |
Richiedente assicurato? | Qualitativa sconnessa |
SEATBELT |
Cintura di sicurezza allacciata? | Qualitativa sconnessa |
CLMAGE |
Età del richiedente | Quantitativa discreta/continua |
LOSS |
Ammontare del danno (migliaia $) | Quantitativa continua |
In R, la matrice dei dati è rappresentata da un data frame:
# Esempio con dati neonati (richiede file neonati.csv nella directory di lavoro)
neo <- read.csv("neonati.csv", sep = ";", header = TRUE)
head(neo)#> Peso settimane fuma
#> 1 2940 38 S
#> 2 2420 36 S
#> 3 2760 39 S
#> 4 2440 35 S
#> 5 3301 42 S
#> 6 2715 36 S
#> 'data.frame': 32 obs. of 3 variables:
#> $ Peso : int 2940 2420 2760 2440 3301 2715 3130 2928 3446 2957 ...
#> $ settimane: int 38 36 39 35 42 36 39 39 42 39 ...
#> $ fuma : chr " S" " S" " S" " S" ...
Un data frame può contenere colonne di tipo diverso (numerico, carattere, fattore), a differenza di una matrice che è omogenea.
In AutoBi alcune variabili sono codificate come numeri
interi pur essendo qualitative. Occorre trasformarle esplicitamente in
fattori.
# Trasformiamo MARITAL in fattore e assegnamo le etichette
AutoBi$MARITAL <- factor(AutoBi$MARITAL)
levels(AutoBi$MARITAL) <- c("married", "single", "widowed", "divorced")
str(AutoBi$MARITAL)#> Factor w/ 4 levels "married","single",..: NA 2 2 1 4 1 2 2 2 2 ...
#> married single widowed divorced NA's
#> 624 650 15 35 16
Possiamo ridurre il numero di livelli unendo alcune categorie:
# Unire "widowed" e "divorced" in "previouslymarried"
levels(AutoBi$MARITAL) <- c("married", "single", "previouslymarried", "previouslymarried")
levels(AutoBi$MARITAL)#> [1] "married" "single" "previouslymarried"
#>
#> married single previouslymarried
#> 624 650 50
cut()La funzione cut() converte una variabile numerica
continua in un fattore ordinato con classi di
valori.
#> [1] 0 95
# 6 classi di uguale ampiezza
CLMAGEclass_eq <- cut(AutoBi$CLMAGE, breaks = 6)
levels(CLMAGEclass_eq)#> [1] "(-0.095,15.8]" "(15.8,31.7]" "(31.7,47.5]" "(47.5,63.3]"
#> [5] "(63.3,79.2]" "(79.2,95.1]"
# Classi di ampiezza diversa (definite manualmente)
CLMAGEclass <- cut(AutoBi$CLMAGE, breaks = c(-1, 15, 24, 36, 50, 95))
levels(CLMAGEclass)#> [1] "(-1,15]" "(15,24]" "(24,36]" "(36,50]" "(50,95]"
#> CLMAGEclass
#> (-1,15] (15,24] (24,36] (36,50] (50,95]
#> 144 280 269 299 159
Nota sulla notazione:
(a, b]significa che la classe includebma nona. I valori fuori dall’intervallo specificato diventanoNA.
# Aggiungere la nuova variabile al data frame
AutoBi <- cbind(AutoBi, CLMAGEclass)
str(AutoBi[, c("CLMAGE", "CLMAGEclass")])#> 'data.frame': 1340 obs. of 2 variables:
#> $ CLMAGE : int 50 28 5 32 30 35 19 34 61 NA ...
#> $ CLMAGEclass: Factor w/ 5 levels "(-1,15]","(15,24]",..: 4 3 1 3 3 3 2 3 5 NA ...
Carica il dataset Cars93 dal package MASS e
classifica almeno 6 variabili secondo lo schema qualitativa/quantitativa
e, dove applicabile, sconnessa/ordinale o discreta/continua.
library(MASS)
data("Cars93")
str(Cars93)
# Scrivi qui la tua classificazione come commenti:
# es. Type: qualitativa ordinale (Small < Compact < Midsize < Large < Van)Suggerimento: usa ?Cars93 per leggere
la descrizione delle variabili.
Utilizziamo il dataset AutoBi. Esegui le seguenti
operazioni:
ATTORNEY in un fattore con etichette
"yes" e "no".CLMSEX in un fattore con etichette
"M" e "F".str() che le trasformazioni siano avvenute
correttamente.Soluzione:
AutoBi$ATTORNEY <- factor(AutoBi$ATTORNEY)
levels(AutoBi$ATTORNEY) <- c("yes", "no")
AutoBi$CLMSEX <- factor(AutoBi$CLMSEX)
levels(AutoBi$CLMSEX) <- c("M", "F")
str(AutoBi[, c("ATTORNEY", "CLMSEX")])#> 'data.frame': 1340 obs. of 2 variables:
#> $ ATTORNEY: Factor w/ 2 levels "yes","no": 1 2 2 1 2 1 1 1 2 2 ...
#> $ CLMSEX : Factor w/ 2 levels "M","F": 1 2 1 1 1 2 1 2 2 1 ...
Usando la variabile LOSS di AutoBi:
range()).quantile()).LOSSclass.Soluzione:
#> [1] 0.005 1067.697
q <- quantile(AutoBi$LOSS)
AutoBi$LOSSclass <- cut(AutoBi$LOSS, breaks = q, include.lowest = TRUE)
levels(AutoBi$LOSSclass)#> [1] "[0.005,0.64]" "(0.64,2.33]" "(2.33,3.99]" "(3.99,1.07e+03]"
#>
#> [0.005,0.64] (0.64,2.33] (2.33,3.99] (3.99,1.07e+03]
#> 336 334 335 335
Rispondi brevemente alle seguenti domande (puoi scrivere le risposte come commenti nel codice):
34121) è una variabile
quantitativa o qualitativa? Motiva la risposta.cut() e alcuni valori del
vettore numerico cadono fuori dagli estremi dei breaks
specificati?# Scrivi le tue risposte qui come commenti:
# 1.
# 2.
# 3.
# Puoi verificare sperimentalmente il punto 3:
x <- c(1, 5, 10, 15, 100)
cut(x, breaks = c(0, 5, 10, 20)) # cosa succede al valore 100?#> [1] (0,5] (0,5] (5,10] (10,20] <NA>
#> Levels: (0,5] (5,10] (10,20]
# ESPLORARE UN DATA FRAME
str(df) # struttura e tipi
head(df) # prime 6 righe
summary(df) # riassunto per colonna
# TRASFORMARE IN FATTORE
x <- factor(x)
levels(x) <- c("etichetta1", "etichetta2")
# UNIRE CATEGORIE
levels(x) <- c("A", "A", "B") # unisce i primi due livelli in "A"
# Quantili
quantile(x) # min, primo/secondo/terzo quartile, max
# CLASSI DI VALORI
cut(x, breaks = n) # n classi di uguale ampiezza
cut(x, breaks = c(a, b, c)) # classi di ampiezza diversa
cut(x, breaks = quantile(x),
include.lowest = TRUE) # classi ai quartili
# VALORI MANCANTI
sum(is.na(x)) # numero di NA
x[!is.na(x)] # rimuovere NA