1 Esercizio

Usiamo il dataset AutoBi del pacchetto insuranceData, che contiene dati su sinistri assicurativi auto. Usando help("AutoBi") possiamo vedere la descrizione dei dati e le variabili contenute nel data frame:

CASENUM: Case number to identify the claim, a numeric vector

ATTORNEY: Whether the claimant is represented by an attorney (=1 if yes and =2 if no), a numeric vector

CLMSEX: Claimant’s gender (=1 if male and =2 if female), a numeric vector

MARITAL: claimant’s marital status (=1 if married, =2 if single, =3 if widowed, and =4 if divorced/separated), a numeric vector

CLMINSUR: Whether or not the driver of the claimant’s vehicle was uninsured (=1 if yes, =2 if no, and =3 if not applicable), a numeric vector

SEATBELT: Whether or not the claimant was wearing a seatbelt/child restraint (=1 if yes, =2 if no, and =3 if not applicable), a numeric vector

CLMAGE: Claimant’s age, a numeric vector

LOSS: The claimant’s total economic loss (in thousands), a numeric vector

1.1 Installazione/Caricamento pacchetti e dati

Se il pacchetto insuranceData non è installato va installato usando install.packages("nome pacchtto"), quindi carichiamo i pacchetti dplyr e insuranceData mediante library(nome pacchetto). Quindi, caricato il data frame mediante data(nome dataset), possiamo esplorarne la struttura mediante str(nome dataset), il nome delle variabili mediante names(nome dataset), la sua dimensionalità (numero di osservazioni e di variabili) mediante dim(nome dataset), e le

# install.packages("insuranceData")  # solo la prima volta
library(dplyr)
library(insuranceData)
data(AutoBi)

str(AutoBi)     # struttura  
#> '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 ...
names(AutoBi)   # nomi variabili
#> [1] "CASENUM"  "ATTORNEY" "CLMSEX"   "MARITAL"  "CLMINSUR" "SEATBELT" "CLMAGE"  
#> [8] "LOSS"
dim(AutoBi)     # dimensioni dataframe
#> [1] 1340    8
head(AutoBi, 8) # prime 8 righe

1.2 La funzione summary

Rimuoviamo la prima colonna (si tratta di un numero identificativo di poca utilitĂ )

AutoBi <- AutoBi[, -1]

La funzione summary() permette di ottenere statistiche riassuntive delle variabili di AutoBi (essa è di particolare utilità per l’esplorazione di variabili numeriche)

summary(AutoBi)
#>     ATTORNEY         CLMSEX         MARITAL         CLMINSUR    
#>  Min.   :1.000   Min.   :1.000   Min.   :1.000   Min.   :1.000  
#>  1st Qu.:1.000   1st Qu.:1.000   1st Qu.:1.000   1st Qu.:2.000  
#>  Median :1.000   Median :2.000   Median :2.000   Median :2.000  
#>  Mean   :1.489   Mean   :1.559   Mean   :1.593   Mean   :1.908  
#>  3rd Qu.:2.000   3rd Qu.:2.000   3rd Qu.:2.000   3rd Qu.:2.000  
#>  Max.   :2.000   Max.   :2.000   Max.   :4.000   Max.   :2.000  
#>                  NA's   :12      NA's   :16      NA's   :41     
#>     SEATBELT         CLMAGE           LOSS         
#>  Min.   :1.000   Min.   : 0.00   Min.   :   0.005  
#>  1st Qu.:1.000   1st Qu.:19.00   1st Qu.:   0.640  
#>  Median :1.000   Median :31.00   Median :   2.331  
#>  Mean   :1.017   Mean   :32.53   Mean   :   5.953  
#>  3rd Qu.:1.000   3rd Qu.:43.00   3rd Qu.:   3.995  
#>  Max.   :2.000   Max.   :95.00   Max.   :1067.697  
#>  NA's   :48      NA's   :189

1.3 Conversione variabili numeriche in factor

Convertiamo le variabili ATTORNEY, CLMSEX, MARITAL, CLMINSUR, SEATBELT in factor. Vediamo le due sintassi (R base e dplyr a confronto).

Creiamo prima di tutto due copie di AutoBi, una verrĂ  usata per R base e una per dplyr.

Auto_rbase <- Auto_dplyr <- AutoBi 

R base

Auto_rbase[, 1:5] <- as.data.frame(
  sapply(Auto_rbase[, 1:5], factor), 
  stringsAsFactors = T)
str(Auto_rbase)
#> 'data.frame':    1340 obs. of  7 variables:
#>  $ ATTORNEY: Factor w/ 2 levels "1","2": 1 2 2 1 2 1 1 1 2 2 ...
#>  $ CLMSEX  : Factor w/ 2 levels "1","2": 1 2 1 1 1 2 1 2 2 1 ...
#>  $ MARITAL : Factor w/ 4 levels "1","2","3","4": NA 2 2 1 4 1 2 2 2 2 ...
#>  $ CLMINSUR: Factor w/ 2 levels "1","2": 2 1 2 2 2 2 2 2 2 2 ...
#>  $ SEATBELT: Factor w/ 2 levels "1","2": 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 ...

dplyr

Auto_dplyr <- Auto_dplyr |> 
  mutate(across(c(ATTORNEY, CLMSEX, MARITAL, 
                  CLMINSUR, SEATBELT), factor))
str(Auto_dplyr)
#> 'data.frame':    1340 obs. of  7 variables:
#>  $ ATTORNEY: Factor w/ 2 levels "1","2": 1 2 2 1 2 1 1 1 2 2 ...
#>  $ CLMSEX  : Factor w/ 2 levels "1","2": 1 2 1 1 1 2 1 2 2 1 ...
#>  $ MARITAL : Factor w/ 4 levels "1","2","3","4": NA 2 2 1 4 1 2 2 2 2 ...
#>  $ CLMINSUR: Factor w/ 2 levels "1","2": 2 1 2 2 2 2 2 2 2 2 ...
#>  $ SEATBELT: Factor w/ 2 levels "1","2": 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 ...

1.4 Selezione di colonne per tipo di variabile

📌 Selezioniamo le variabili di tipo numerico, cioè CLMAGE e LOSS.

R base

Auto_rbase[, sapply(Auto_rbase, is.numeric)]

dplyr

select(Auto_dplyr, where(is.numeric))
# In alternativa
#Auto_dplyr |> select(where(is.numeric))

1.5 Selezione di una variabile e di osservazioni per condizioni logiche

📌 Selezioniamo la variabile età (CLMAGE) e filtra solo i soggetti con età inferiore a 20 anni.

💡 subset() è una funzione R base che permette di filtrare righe e selezionare colonne con una sintassi più leggibile, senza dover ripetere il nome del data frame in ogni condizione:

R base

subset(Auto_rbase, 
       subset = CLMAGE < 20, 
       select = CLMAGE)
# In alternativa
# AutoBi$CLMAGE[AutoBi$CLMAGE < 20]

dplyr

Auto_dplyr |> 
  select(CLMAGE) |> 
  filter(CLMAGE < 20)

Esercizio veloce
In cosa differiscono i due comandi?

Auto_rbase$CLMAGE[Auto_rbase$CLMAGE < 20]
subset(Auto_rbase, subset = CLMAGE < 20, select = CLMAGE)

📌 Selezioniamo le donne (CLMSEX == 2) di età inferiore ai 40 anni, sposate (MARITAL == 1) o divorziate (MARITAL == 4), con perdite (LOSS) superiori a 5.000 dollari.

R base

Auto_rbase_sub <- subset(Auto_rbase,
              subset = (MARITAL == 1 | MARITAL == 4) &
                       (CLMSEX == 2) &
                       (CLMAGE < 40) &
                       (LOSS > 5))
Auto_rbase_sub

dplyr

Auto_dplyr_sub <- Auto_dplyr |>
  filter((MARITAL == 1 | MARITAL == 4) &
         (CLMSEX == 2) &
         (CLMAGE < 40) &
         (LOSS > 5))
Auto_dplyr_sub

📌 Selezioniamo le variabili MARITAL e CLMINSUR per i soggetti rappresentati da un avvocato (ATTORNEY == 1) ed escludiamo i valori mancanti con na.omit().

R base

Auto_rbase_sub2 <- na.omit(
  Auto_rbase[Auto_rbase$ATTORNEY == 1, 
             c("MARITAL", 
               "CLMINSUR")])
colSums(is.na(Auto_rbase_sub2))
#>  MARITAL CLMINSUR 
#>        0        0

dplyr

Auto_dplyr_sub2 <- AutoBi |>
  filter(ATTORNEY == 1) |>
  select(MARITAL, CLMINSUR) |>
  na.omit() # alternativa:  drop_na()
colSums(is.na(Auto_dplyr_sub2))
#>  MARITAL CLMINSUR 
#>        0        0

1.6 Aggiungere colonne

📌 Aggiungiamo una nuova colonna LOGloss con il logaritmo della variabile LOSS

R base

Auto_rbase$LOGloss <- log(Auto_rbase$LOSS) 
Auto_rbase

dplyr

Auto_dplyr <- mutate(Auto_dplyr, LOGloss = log(LOSS))
Auto_dplyr

📌 Creiamo una nuova colonna LOSS_cat che contenga la divisione di LOSS in classi. In particolare consideriamo la divisione

Classe Intervallo
"Very Low" [0.005,0.640)
"Low" [0.640–2.331)
"High" [2.331–3.995)
"Very High" [3.995–1067.697]

đź’ˇ Usiamo la funzione cut(): cut() trasforma una variabile numerica continua in una variabile categoriale (factor), suddividendo i valori in intervalli. I principali argomenti sono:

Argomento Significato Default
x il vettore numerico da suddividere
breaks valori che delimitano gli intervalli
labels etichette da assegnare a ciascun intervallo nomi intervalli
include.lowest include il valore minimo nell’intervallo più basso FALSE
right intervalli chiusi a destra (a, b] TRUE

⚠️ Il numero di labels deve essere uguale al numero di intervalli, che è sempre length(breaks) - 1. Con 5 breaks si ottengono 4 intervalli e quindi 4 etichette.

⚠️ Gli intervalli sono per default aperti a sinistra e chiusi a destra — cioè (a, b]. Con include.lowest = TRUE il primo intervallo diventa chiuso anche a sinistra: [a, b]. Con right = FALSE gli intervalli diventano [a, b), chiusi a sinistra.

R base

Auto_rbase$LOSS_cat <- cut(
  Auto_rbase$LOSS,
  breaks = c(0.005, 0.640, 2.331, 3.995, 1067.697),
  labels = c("Very Low", "Low",
             "High", "Very High"),
  include.lowest = TRUE, 
  right = FALSE
)

table(Auto_rbase$LOSS_cat)
#> 
#>  Very Low       Low      High Very High 
#>       334       336       335       335

dplyr

Auto_dplyr <- Auto_dplyr |>
  mutate(LOSS_cat = cut(
    LOSS,
    breaks = c(0.005, 0.640, 2.331, 3.995, 1067.697),
    labels = c("Very Low", "Low", "High", "Very High"),
    include.lowest = TRUE,
    right = FALSE
  ))

Auto_dplyr |> count(LOSS_cat)

Esercizio veloce
Si crei una nuova variabile CLMAGE_cat con CLMAGE divisa in classi. Ad esempio si consideri

Classe Intervallo
"Under18" [0,18]
"Working" (18–67]
"Retirement" (67–95]
Auto_dplyr <- Auto_dplyr |>
  mutate(CLMAGE_cat = cut(
    CLMAGE,
    breaks = c(0, 18, 67, 95),
    labels = c("Under18", "Working", "Retirement"),
    include.lowest = TRUE
  ))

Auto_dplyr |> count(CLMAGE_cat)

1.7 Cheatsheet Rapida

# Pacchetti
install.packages("pacchetto") # Istalla
library(pacchetto)            # Carica
data(df)                      # Dataframe in pacchetto

# Selezione colonne numeriche con dplyr
select(df, where(is.numeric)) 

# Divide x in intervalli scelti con etichette, 
# includendo il valore minimo e del tipo (a,b]
cut(x,
  breaks = vec,
  labels = names,
  include.lowest = TRUE, 
  right = FALSE
)