Analisi di 46 milioni di record con R. Auto di lusso e redditi bassi

Un recente articolo di IlSole24Ore/Infodata riporta la visualizzazione dei comuni  dove sono presenti contemporaneamente dichiarazioni dei redditi basse e auto di lusso. Non avendo accesso ai dati utilizzati dal Sole ho ricercato i dati ufficiali del Ministero dei Trasporti e Ministero delle Finanze e  ho rivisto l’analisi cercando, se possibile,  di migliorarla.

E’ bene ricordare che non parliamo di persone che hanno un’auto di lusso e presentano dichiarazioni a zero, ma di Comuni dove sono presenti contemporaneamente  auto di lusso e dichiarazioni basse. Dove la compresenza di queste due variabili mostra frequenze relative  che si discostano dalla media è il segnale che qualche anomalia è in corso in quel territorio, non necessariamente un caso di evasione fiscale. Ad esempio può esserci  maggiore distanza economica tra gruppi sociali rispetto alla media del paese.

Tutto il codice sviluppato è disponibile sul mio account GitHub.

Un dataset da 46 milioni di record

46 milioni di record

La prima sorpresa interessante è stata la dimensione del dataset originario. Nei 20 archivi regionali  dei veicoli registrati al Ministero dei Trasporti che ho caricato e fuso in un dataset unico, sono infatti contenuti oltre 52 Milioni di record (!). Solo pochi anni fa un volume del genere mi avrebbe richiesto un server cpn DB dedicato o almeno un software capace di girare in parallelo su più processori. Oggi con R sono riuscito a gestire senza  grossi problemi l’intero dataset sul mio PC.

A parte qualche palese errore come un veicolo immatricolato nel 1854, i dati sembrano abbastanza puliti. Dei 20 campi disponibili (inclusi “Assicurazione in regola”, “Età intestatario, “Sesso” etc.) useremo solo comune, provincia, cilindrata, uso, destinazione, Kw.

Il seguente script legge tutti i file il cui nome cominca con “parco” come parco_Lombardia, parco_Veneto etc. e li fonde insieme in unico dataframe “tbl” da 52 milioni di osservazioni

files <- list.files(path="C:/your/path", pattern="parco*.*") 
files setwd("C:/your/path") 
tbl = lapply(files, read_csv) %>% bind_rows()

Le giuste metriche

La seconda sorpresa l’ho avuta utilizzando gli stessi criteri utilizzati dal Sole per filtrare le sole auto di lusso tra i 52 Milioni di veicoli registrati: “veicoli con una cilindrata superiore ai 3mila cc e una potenza superiore ai 200kW. Si tratta di 43mila automobili sugli oltre 8 milioni acquistati dal 2012 ad oggi, lo 0,54% del totale”. 

In questa definizione  sono infatti presenti  autocarri e pullman -con cilindrate che superano abbondantemente i 10mila cc– e anche le automobili utilizzate per il noleggio ad esempio per i  matrimoni. Ho escluso anche queste perchè trattandosi di asset aziendali non transitano dal reddito delle persone fisiche. Con questo codice applico i filtri e raggruppo i dati per comune di residenza, contando le auto di lusso così raggruppate.

tbl_luxury<-tbl%>%
  filter(tipo_veicolo=="A" & kw>=200 & cilindrata>=3000 
  & destinazione=="AUTOVETTURA PER TRASPORTO DI PERSONE" 
  & uso =="PROPRIO") %>%
  select(tipo_veicolo, comune_residenza, provincia_residenza, regione_residenza, marca, cilindrata, kw, destinazione, uso, data_immatricolazione)

tbl_luxury_group<-tbl_luxury %>% 
  group_by(comune_residenza, provincia_residenza, regione_residenza) %>% 
  summarise(auto_lusso=n()) 

A differenza del Sole24Ore ho deciso di tenere nell’analisi anche le auto acquistate prima del 2012. Se infatti un’auto normale di sette anni comincia ad essere “vecchia”, il ciclo di vita delle auto di lusso è completamente diverso. Una Rolls Royce degli anni ’60 continua ad essere un’auto di lusso anche oggi, una Ferrari Testarossa dei primi ’90 vale circa 100.000 Euro, e i costi di gestione e manutenzione sono gli stessi o anche superiori rispetto ai modelli attuali. Dunque ho tenuto tutte le auto di lusso registrate ( e non rottamate), indipendentemente dalla loro età.

Sono così individuate complessivamente circa 109.000 auto di lusso,  lo 0,28% del totale. Rispetto all’analisi del Sole ho preferito però prendere in considerazione il numero di auto di lusso pro-capite (rispetto alla popolazione che ha presentato le dichiarazioni) e non la percentuale auto di lusso rispetto al totale auto, ritenendo quest’ultimo indicatore meno significativo specialmente in casi dove, per necessità locali (ad esempio in aree con pochi trasporti pubblici, o aree rurali o paesi montani di difficile accesso), il numero di auto normali è particolarmente elevato  e  “nasconde” così in qualche modo la quota auto di lusso.

Meno problematica la lettura delle dichiarazioni (raggruppate per comune). Anche in questo caso si tratta di open data del Ministero delle Finanze ma i volumi sono decisamente più ridotti: soli 8.000 record e 51 variabili osservate per le dichiarazioni 2017 relative all’anno 2016.

Incrociare i dati auto di lusso/dichiarazioni basse

Quando mettiamo insieme i due dataset però, ci rendiamo conto che il codice ISTAT del comune, utilizzato nel file dichiarazioni, non è presente nel dataset autoveicoli. Dobbiamo quindi usare il campo “Comune di Residenza” che contiene la stringa con il nome del comune ed avere l’accortezza di mettere in chiave anche la provincia (o la sigla) in modo da evitare la sovrapposizione di comuni con lo stesso nome ma in province diverse come ad esempio San Teodoro (ME) e San Teodoro (OT). Anche così perderemo circa 300 comuni, tipicamente quelli con spazi e nomi composti come Albino-Albein, Campiglione-Fenile, Cassina De’Pecchi  etc che sono scritti con lievi differenze tra i due dataset. Li individuo facilmente con il seguente codice

# comuni che hanno auto di lusso ma non hanno dichiarazioni
test_mancanti<-tbl_luxury_group %>% anti_join(dichiarazioni_2016, 
by = c("comune_residenza"="comune"))

e possono eventualmente essere recuperati editando manualmente uno dei due file.

Ho usato i quartili per suddividere le due variabili continue pc_redditi_bassi e auto_lusso_procapite in tre categorie “bassa”, “media” e  “alta”. Qui di seguito l’applicazione sulla variabile redditi, usando le funzioni quantile() e cut():

#  uso percentile per categorie redditi bassi: bassa/media/alta
qp<-quantile(dichiarazioni_2016$pct_redditi_bassi,c(0,1/3, 2/3,1),
na.rm = TRUE)
dichiarazioni_2016<-dichiarazioni_2016 %>%
mutate(cat_redditi_bassi=cut(pct_redditi_bassi, breaks=qp, 
labels=c("bassa","media", "alta")))

Il dataset finale può essere stampato in una tabella di facile consultazione con tutti i comuni che presentano l’accoppiata auto di lusso/redditi bassi con valori inusuali e/o essere ulteriormente elaborata graficamente. Questo è il codice per ottenere la tabella con i soli valori elevati di auto di lusso pro-capite e dichiarazione dei redditi basse.


test_alti<-test %>%
  filter(cat_redditi_bassi=="alta" & cat_auto_lusso=="alta") %>% 
  select(comune_residenza,provincia_residenza, regione_residenza,numero_contribuenti,tot_redditi_bassi,pct_redditi_bassi, auto_lusso,auto_lusso_procapite)

Di seguito la mappa interattiva dei comuni con auto di lusso e dichiarazioni dei redditi basse