Lanciare una query sui server SDMX di ISTAT
Come abbiamo visto nelle puntate precedenti1 i comandi del package RSDMX2 consentono di scaricare interi dataset dai server ISTAT3. Sono gli stessi dati presenti sul servizio Informazione statistica di Istat 4.
Oggi cerco di spiegare come lanciare una query sui server SDMX di ISTAT. Lo scopo è:
- scaricare solo i dati che ci servono e non tutto il file, rendendo l’acquisizione delle informazioni pià veloce;
- ridurre il traffico in rete;
- forse, dico forse, evitare che i sistemi di Istat vengano sovraccaricati da troppo traffico (in realtà non so cosa sia più oneroso in termini di consumo di risorse).
Riassumiamo e partiamo
- Carichiamo le librerie che ci servono:
library(rsdmx)
library(dplyr)
- facciamoci dare la lista flussi da Istat e trasformiamola in un dataframe:
dataflows <- readSDMX(providerId = "ISTAT", resource = "dataflow")
istatFlows <- as.data.frame(dataflows)
- guardiamo le prime 5 righe e alcune colonne:
istatT <- istatFlows[1:5, c("id", "dsdRef", "Name.it")]
knitr::kable(istatT)
id | dsdRef | Name.it |
---|---|---|
12_60 | DCCV_CONSACQUA | Distribuzione di acqua potabile |
149_327 | DCSC_RETRCONTR1O | Orario contrattuale annuo lordo, netto, ferie e altre ore di riduzione |
22_315 | DCIS_POPORESBIL1 | Popolazione residente - bilancio |
97_366 | DCCN_PROTSOC | Conti della Protezione sociale (milioni di euro) |
101_22 | DCSP_FITOSANITARI | Fitosanitari |
- cerco il nome del flusso
Tasso di disoccupazione
dato che conosco il suo codice151_914
(dalle puntate precedenti):
id_flusso <- istatFlows[istatFlows$id %in% c("151_914"), c("dsdRef")]
- ok, adesso ci serve la data structure definition (DSD) del flusso dati. La scarichiamo con
rsdmx
:
dsd <- readSDMX(providerId = "ISTAT", resource = "datastructure", resourceId=id_flusso)
La nostra dsd è una classe S4. Una classe S4 è una struttura dati contenente diversi attributi (denominati slots) di tipo predeterminato. Gli oggetti S4 possono avere una struttura ricorsiva. Dato che questo non è un corso di programmazione ad oggetti, se volete saperne di più sulle classi S4 leggete gli ottimi paper che ho messo in nota5.
Ai nostri scopi ci basti sapere che si tratta di un albero che possiamo espandere e che contiene altri oggetti, sapendo che determinate informazioni sono sempre nello stesso nodo. Quindi possiamo cercarle con istruzioni strutturate.
Alla ricerca delle dimensioni: cosa e dove sono?
Ogni misura (valore aggregato) è descritta da alcune proprietà, come l’unità di misura, la frequenza temporale e l’aggregazione geografica. In SDMX queste proprietà sono chiamate dimensioni e rappresentano le equivalenti dimensioni dei cubi di dati del data warehouse dove l’informazione è mantenuta6.
Ci serve sapere quante e quali dimensioni ha il nostro flusso dati e in che ordine si presentano. Sta scritto nel DSD.
Se chiediamo a R:
slotNames(dsd)
## [1] "organisationSchemes" "concepts" "codelists"
## [4] "datastructures" "xmlObj" "schema"
## [7] "header" "footer"
otteniamo la lista degli slot: le dimensioni sono dentro lo slot "datastructures"
.
Estrarre le dimensioni e le liste dei codici
Con queste istruzioni ricaviamo le dimensioni e le riportiamo in una tabella:
datastructures <- slot(dsd, "datastructures")
components <- slot(slot(datastructures, "datastructures")[[1]], "Components")
dimensioni <- as.data.frame(components)
dimensioni <- dimensioni %>%
filter(component == "Dimension") %>%
select(component, conceptRef, codelist)
knitr::kable(dimensioni)
component | conceptRef | codelist |
---|---|---|
Dimension | FREQ | CL_FREQ |
Dimension | CITTADINANZA | CL_CITTADINANZA |
Dimension | DURATA_DISOCCUPAZ | CL_DURATA |
Dimension | CLASSE_ETA | CL_ETA1 |
Dimension | ITTER107 | CL_ITTER107 |
Dimension | SESSO | CL_SEXISTAT1 |
Dimension | TIPO_DATO | CL_TIPO_DATO_FOL |
Dimension | TITOLO_STUDIO | CL_TITOLO_STUDIO |
Bene, ci sono 8 dimensioni in questo flusso dati. Vediamo anche i nomi delle codelist, vale a dire le liste dei codici che descrivono le variabili e contengono le label.
Estraiamo la lista dei codici per la frequenza CL_FREQ
:
cl <- as.data.frame(slot(dsd, "codelists"), codelistId = "CL_FREQ")
cl <- cl %>%
select(id, label.it)
knitr::kable(cl)
id | label.it |
---|---|
A | annuale |
B | business (non supportato) |
D | giornaliero |
E | event (non supportato) |
H | semestrale |
M | mensile |
Q | trimestrale |
W | settimanale |
e anche per la cittadinanza CL_CITTADINANZA
:
cl <- as.data.frame(slot(dsd, "codelists"), codelistId = "CL_CITTADINANZA")
cl <- cl %>%
select(id, label.it)
knitr::kable(cl)
id | label.it |
---|---|
ITL | italiano-a |
FRG | straniero-a |
EU27 | di paese dell’Unione europea a 27 |
TOTAL | totale |
APO | apolide |
FRGAPO | straniero-a/apolide |
EXTEU27 | di paese extra Unione europea a 27 paesi |
Ci siamo quasi: comporre la query.
Con il nostro rsdmx possiamo comporre una query come questa:
sdmx.data <- readSDMX(providerId = "ISTAT",
resource = "data",
flowRef = "151_914",
key = list("A",
"ITL+FRG",
NULL,
NULL,
NULL,
NULL,
NULL,
NULL),
start = 2017,
end = 2018,
dsd = F)
## -> Fetching 'http://sdmx.istat.it/SDMXWS/rest/data/151_914/A.ITL+FRG....../all/?startPeriod=2017&endPeriod=2018'
Spieghiamola: con il pezzo di istruzione key = list("A", "ITL+FRG", NULL, NULL, NULL, NULL, NULL, NULL)
ho chiesto di avere solo i dati annuali "A"
per gli italiani e gli stranieri "ITL+FRG"
, senza imporre filtri sulle altre dimensioni (le prime 2 dimensioni + 6 NULL
= 8 dimensioni). Ho anche stabilito il periodo di inizio start = 2017
e di fine dei dati che mi interessano end = 2018
e alla fine NON ho chiesto il dsd dsd = F
, ho già scaricato il DSD prima.
Nota:
- ho usato l’ordine della tabella che ho trovato nello slot “datastructures”.
readSDMX
ha composto un URI, una istruzione http. Lo si può salvare e usare direttamente per le prossime volte.
Con questre istruzioni associamo i dati al loro dsd che abbiamo scaricato prima:
sdmx.data <- setDSD(sdmx.data, dsd)
disoccupazione <- as.data.frame(sdmx.data, labels = T)
knitr::kable(head(disoccupazione))
ITTER107 | ITTER107_label.en | ITTER107_label.it | TIPO_DATO | TIPO_DATO_label.en | TIPO_DATO_label.it | SESSO | SESSO_label.en | SESSO_label.it | CLASSE_ETA | CLASSE_ETA_label.en | CLASSE_ETA_label.it | TITOLO_STUDIO | TITOLO_STUDIO_label.en | TITOLO_STUDIO_label.it | CITTADINANZA | CITTADINANZA_label.en | CITTADINANZA_label.it | DURATA_DISOCCUPAZ | DURATA_DISOCCUPAZ_label.en | DURATA_DISOCCUPAZ_label.it | FREQ | FREQ_label.en | FREQ_label.it | obsTime | obsValue |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
IT | Italy | Italia | UNEM_R | unemployment rate | tasso di disoccupazione | 1 | males | maschi | Y_GE15 | 15 years and over | 15 anni e più | 11 | tertiary (university, doctoral and specialization courses) | laurea e post-laurea | FRG | foreign | straniero-a | TOTAL | total | totale | A | annual | annuale | 2017 | 8.97655 |
IT | Italy | Italia | UNEM_R | unemployment rate | tasso di disoccupazione | 1 | males | maschi | Y_GE15 | 15 years and over | 15 anni e più | 3 | primary school certificate, no educational degree | licenza di scuola elementare, nessun titolo di studio | FRG | foreign | straniero-a | TOTAL | total | totale | A | annual | annuale | 2017 | 15.92737 |
IT | Italy | Italia | UNEM_R | unemployment rate | tasso di disoccupazione | 1 | males | maschi | Y_GE15 | 15 years and over | 15 anni e più | 4 | lower secondary school certificate | licenza di scuola media | FRG | foreign | straniero-a | TOTAL | total | totale | A | annual | annuale | 2017 | 12.73334 |
IT | Italy | Italia | UNEM_R | unemployment rate | tasso di disoccupazione | 1 | males | maschi | Y_GE15 | 15 years and over | 15 anni e più | 7 | upper and post secondary | diploma | FRG | foreign | straniero-a | TOTAL | total | totale | A | annual | annuale | 2017 | 12.14967 |
IT | Italy | Italia | UNEM_R | unemployment rate | tasso di disoccupazione | 1 | males | maschi | Y_GE15 | 15 years and over | 15 anni e più | 99 | total | totale | FRG | foreign | straniero-a | TOTAL | total | totale | A | annual | annuale | 2017 | 12.60663 |
IT | Italy | Italia | UNEM_R | unemployment rate | tasso di disoccupazione | 2 | females | femmine | Y_GE15 | 15 years and over | 15 anni e più | 11 | tertiary (university, doctoral and specialization courses) | laurea e post-laurea | FRG | foreign | straniero-a | TOTAL | total | totale | A | annual | annuale | 2017 | 13.50486 |
e ottengo il mio dataframe che comprende le labels!
Molto più veloce!
Si, è molto più veloce! Usate le query per scaricare solo quello che vi serve e tenete le DSD salvate sul vostro pc. Spero che l’intero standard SDMX risulti più chiaro. Buon lavoro!
- https://datalab.updog.co/2018/06/09/2018-06-09-leggere-la-statistica-pubblica-con-r/ [return]
- https://datalab.updog.co/2018/06/16/2018-06-16-statistica-pubblica-e-r-parte-2/ [return]
- https://datalab.updog.co/2018/06/24/2018-06-24-leggere-la-statistica-ufficiale-con-r-cosa-fare-quando-il-server-sdmx-di-istat-non-funziona/ [return]
- http://dati.istat.it/ [return]
- ringrazio sentitamente gli autori che hanno messo a disposizione tanta conoscenza e tanta chiarezza. In italiano: https://alpha.dmi.unict.it/~alaimos/uploads/2013-2014/da-2013-14-introduction-to-r.pdf http://people.idsia.ch/~azzimonti/ProgrammazioneAvanzataInR.pdf. In inglese: http://adv-r.had.co.nz/OO-essentials.html#s4 [return]
- per maggiori dettagli sullo standard vedi: http://ec.europa.eu/eurostat/web/sdmx-web-services/data-struct-def [return]