Data Analytics
Da Tabelle Frequenza Barplot Pie
Data Analysis## ============================================================================
## DATA ANALYSIS — Lezione 2/3
## Tabelle di frequenza semplici,
## a doppia e tripla entrata, barplot e grafici a torta
## ============================================================================
# Preambolo
library(insuranceData)
data("AutoBi")
# Ricodifica variabili (ripresa dalla Lezione 1 di DA)
AutoBi$ATTORNEY <- factor(AutoBi$ATTORNEY)
levels(AutoBi$ATTORNEY) <- c("yes", "no")
AutoBi$CLMSEX <- factor(AutoBi$CLMSEX)
levels(AutoBi$CLMSEX) <- c("M", "F")
AutoBi$MARITAL <- factor(AutoBi$MARITAL)
levels(AutoBi$MARITAL) <- c("married", "single", "previouslymarried", "previouslymarried")
# Variabile quantitativa in classi
CLMAGEclass <- cut(AutoBi$CLMAGE, breaks = c(-1, 15, 24, 36, 50, 95))
AutoBi <- cbind(AutoBi, CLMAGEclass)
# 1. TABELLE DI FREQUENZA SEMPLICI ----
## 1.1 Frequenze assolute — table()
?table
tabella_att <- table(AutoBi$ATTORNEY)
tabella_att # stampa la tabella
str(tabella_att) # è un array con una dimensione
tabella_att["yes"] # accesso per nome
tabella_att[1] # accesso per posizione
dim(tabella_att) # numero di modalità
tabella_mar <- table(AutoBi$MARITAL)
tabella_mar
## 1.2 Frequenze relative — prop.table()
# ⚠ Attenzione agli NA: length() li conta, margin.table() no
freqrel_errata <- table(AutoBi$MARITAL) / length(AutoBi$MARITAL)
sum(freqrel_errata) # non fa 1!
totale <- margin.table(table(AutoBi$MARITAL)) # conta solo i casi validi
totale
freqrel <- table(AutoBi$MARITAL) / totale
sum(freqrel) # ora fa 1
# Metodo diretto con prop.table()
prop.table(table(AutoBi$MARITAL))
## 1.3 Variabili quantitative: usare le classi
# table() su variabile continua → poco leggibile
table(AutoBi$CLMAGE) # tanti valori distinti
# Molto meglio con le classi
table(CLMAGEclass)
prop.table(table(CLMAGEclass))
round(prop.table(table(CLMAGEclass)), 3)
## 1.4 Livelli vuoti nei fattori
AutoBi$CLMSEX <- factor(AutoBi$CLMSEX) # già fattore, ma per sicurezza
solo_maschi <- AutoBi[AutoBi$CLMSEX == "M", ]$CLMSEX
table(solo_maschi) # mostra "F" con frequenza 0
droplevels(solo_maschi) # elimina livelli vuoti
table(droplevels(solo_maschi))
# 2. TABELLE A DOPPIA ENTRATA ----
## 2a. Frequenze assolute congiunte
tab1 <- table(AutoBi$CLMSEX, AutoBi$ATTORNEY)
tab1
# Nota: prima variabile → righe; seconda variabile → colonne
## 2b. Distribuzioni marginali
margin.table(tab1, 1) # marginale di CLMSEX (somma per riga)
margin.table(tab1, 2) # marginale di ATTORNEY (somma per colonna)
margin.table(tab1) # totale complessivo
## 2c. Frequenze relative
# Congiunte (ogni cella / totale generale)
prop.table(tab1)
# Condizionate di riga (distribuzione di ATTORNEY dato CLMSEX)
# → ogni riga somma a 1
prop.table(tab1, 1)
round(prop.table(tab1, 1), 3)
# Condizionate di colonna (distribuzione di CLMSEX dato ATTORNEY)
# → ogni colonna somma a 1
prop.table(tab1, 2)
round(prop.table(tab1, 2), 3)
# 3. ASSOCIAZIONE TRA VARIABILI ----
# Due variabili sono ASSOCIATE se le distribuzioni condizionate
# di una variano al variare delle modalità dell'altra.
# Se le condizionate sono simili tra loro e alla marginale → INDIPENDENTI.
# Quale tabella leggere?
# → condizionata rispetto alla variabile ESPLICATIVA (indipendente)
## 3a. Esempio di ASSOCIAZIONE: ATTORNEY (risposta) ~ LOSS (esplicativa)
AutoBi$LOSSclass <- cut(AutoBi$LOSS, breaks = c(0, 0.5, 2, 4, 8, 1100))
# Distribuzione marginale di ATTORNEY (riferimento)
tot <- prop.table(table(AutoBi$ATTORNEY))
tot
# Tabella congiunta
tabella_al <- table(AutoBi$ATTORNEY, AutoBi$LOSSclass)
tabella_al
# Frequenze condizionate: ATTORNEY | LOSSclass (colonne)
prof_col <- prop.table(tabella_al, 2)
# Affiancate alla distribuzione marginale di ATTORNEY
cbind(round(prof_col, 3), marginale = round(tot, 3))
# Si vede chiaramente: al crescere del danno, cresce il ricorso all'avvocato
# → le due variabili sono ASSOCIATE
# Deviazioni profilo di colonna
dev_prof_col <- prof_col -
matrix(rep(tot,ncol(prof_col)),
nrow(prof_col), ncol(prof_col),
byrow = F)
dev_prof_col
## 3b. Esempio di QUASI-INDIPENDENZA: CLMSEX ~ CLMAGEclass
tabella_sa <- table(AutoBi$CLMSEX, CLMAGEclass)
prof_col <- prop.table(tabella_sa, 2)
round(prof_col, 3)
dev_prof_col <- prof_col -
matrix(rep(tot,ncol(prof_col)),
nrow(prof_col), ncol(prof_col),
byrow = F)
dev_prof_col
# Le distribuzioni condizionate del sesso non variano sistematicamente
# con la classe di età → le variabili appaiono indipendenti
# NB: per decidere formalmente se le differenze sono trascurabili
# occorre ricorrere a strumenti di statistica inferenziale
## Esercizio 2
# Costruisci la tabella congiunta di `CLMSEX` e `MARITAL`:
# 1. Calcola le distribuzioni marginali di entrambe le variabili.
# 2. Calcola le frequenze condizionate di `MARITAL` dato `CLMSEX` (ogni riga somma a 1).
# 3. Affianca le frequenze condizionate alla distribuzione marginale di `MARITAL` con `rbind()`.
# 4. Le due variabili sembrano associate?
#0.
tab_sm <- table(AutoBi$CLMSEX, AutoBi$MARITAL)
tab_sm # Frequenze assolute congiunte
prop.table(tab_sm) # Frequenze relative congiunte
#1.
margin.table(tab_sm, 1)
prop.table(margin.table(tab_sm, 1))
margin.table(tab_sm, 2)
prop.table(margin.table(tab_sm, 2))
#2.
prop.table(tab_sm, margin = 1)
#3.
rbind(prop.table(tab_sm, margin = 1),
prop.table(margin.table(tab_sm, 2)))
# 4. Le distribuzioni condizionate di MARITAL per sesso
# non differiscono molto dalla marginale → variabili tendenzialmente indipendenti
# Esercizio 3 — Donne al volante, pericolo costante?
# Esplora se il sesso del richiedente è associato
# all'ammontare del danno subito.
# 1. Crea `LOSSclass_q` suddividendo `LOSS` in base
# ai quartili (`quantile()`), con `include.lowest = TRUE`.
# 2. Costruisci la tabella congiunta di `CLMSEX` e `LOSSclass_q`.
# 3. Calcola le frequenze di `CLMSEX` condizionate a `LOSSclass_q` (colonne).
# 4. Calcola le frequenze di `LOSSclass_q` condizionate a `CLMSEX` (righe).
# 5. Confronta la distribuzioni condizionate
# con le rispettive marginali.
# Le variabili sono associate?
# 1.
table(AutoBi$CLMSEX)
prop.table(table(AutoBi$CLMSEX))
# 2.
AutoBi$LOSSclass_q <- cut(AutoBi$LOSS,
breaks = quantile(AutoBi$LOSS),
include.lowest = TRUE)
levels(AutoBi$LOSSclass_q)
# 3.
tab_sq <- table(AutoBi$CLMSEX, AutoBi$LOSSclass_q)
tab_sq
# 4. CLMSEX | LOSSclass_q
round(prop.table(tab_sq, 2), 3)
# 5. LOSSclass_q | CLMSEX
round(prop.table(tab_sq, 1), 3)
# 6.
marginale_loss <- round(prop.table(table(AutoBi$LOSSclass_q)), 3)
rbind(round(prop.table(tab_sq, 1), 3),
marginale = marginale_loss)
# Le distribuzioni condizionate di LOSSclass per sesso
# sono molto simili alla marginale → le variabili sembrano indipendenti
# Tabelle a tre entrate
# Costruiamo una tabella a tre entrate (un array)
# con ATTORNEY, LOSSclass, CLMSEX
tab3 <- table(AutoBi$ATTORNEY, AutoBi$LOSSclass, AutoBi$CLMSEX)
str(tab3)
tab3[,, "M"] # MASCHI
tab3["yes",, "M"] # MASCHI seguiti da avvocati
tab3["yes","(0,0.5]", "M"] # MASCHI seguiti da avvocati con danni (0, 0.5]
tab3[1,1,1]
# BARPLOT ----
# barplot di "Ricorso all' avvocato"
# Frequenze assolute
barplot(table(AutoBi$ATTORNEY),
main = "Ricorso all'avvocato",
ylab = "Frequenze assolute",
xlab = "Avvocato",
col = c("darkred", "darkblue"))
# Frequenze relative
barplot(prop.table(table(AutoBi$ATTORNEY)),
main = "Ricorso all'avvocato",
ylab = "Frequenze relative",
xlab = "Avvocato",
col = c("darkred", "darkblue"))
# barplot in orizzontale di MARITAL
barplot(sort(prop.table(table(AutoBi$MARITAL)), decreasing = TRUE),
main = "Stato Civile",
ylab = "",
horiz = T,
xlab = "Frequenze relative",
col = c("darkred", "darkblue", "darkgreen"),
cex.names = 0.45,
las = 1)
# barplot per tabelle a doppia entrata
# Consideriamo Genere e Tutela legale
tab_ga <- table(AutoBi$CLMSEX,
AutoBi$ATTORNEY)
# Barplot affiancati
barplot(tab_ga,
beside = T,
main = "Ricorso all'avvocato per genere",
ylab = "Freq. Assolute",
xlab = "Avvocato",
legend = T,
ylim = c(0,600),
col = c("darkred", "darkblue"))
barplot(prop.table(tab_ga),
beside = T,
main = "Ricorso all'avvocato per genere",
ylab = "Freq. Assolute",
xlab = "Avvocato",
legend = T,
ylim = c(0,1),
col = c("darkred", "darkblue"))
# Barplot impilati (frequenze genere | Avvocato)
barplot(prop.table(tab_ga, 2),
beside = F,
main = "Ricorso all'avvocato per genere",
ylab = "Freq. Assolute",
xlab = "Avvocato",
legend = T,
ylim = c(0, 1.5),
col = c("darkred", "darkblue"))
# Grafico a barre
pie(prop.table(table(AutoBi$MARITAL)),
main = "Stato civile",
col = c("darkred", "darkblue", "darkgreen"),
labels = paste0(levels(AutoBi$MARITAL), "\n",
round(prop.table(table(AutoBi$MARITAL)),3) * 100, "%"))
# Esercizio 4
# Usando il dataset `Cars93` (`MASS`):
# 1. Costruisci il barplot della variabile `Type`.
# 2. Ordina le barre in senso decrescente di frequenza.
# 3. Costruisci un barplot affiancato che mostri la
# distribuzione di `Type` separatamente per `Origin` (USA vs non-USA).
#💡 Usa `legend = TRUE` nel barplot per aggiungere automaticamente la legenda.
library(MASS)
data(Cars93)
# 1.
barplot(table(Cars93$Type),
main = "Tipo di auto")
# 2.
barplot(sort(table(Cars93$Type), decreasing = TRUE),
main = "Tipo di auto (ordinato)")
# 3.
tab_ot <- table(Cars93$Origin, Cars93$Type)
barplot(tab_ot,
beside = TRUE,
main = "Tipo di auto per origine",
legend = TRUE,
args.legend = list(bty = "n"))
tab_to <- table(Cars93$Type, Cars93$Origin)
barplot(tab_to,
beside = TRUE,
main = "Tipo di auto per origine",
legend = TRUE,
args.legend = list(bty = "n"))