1. Introduzione all’API SDMX
SDMX (Statistical Data and Metadata eXchange) è uno standard internazionale ISO 17369 per lo scambio di dati e metadati statistici. ISTAT implementa questo standard attraverso un servizio web RESTful disponibile all’indirizzo https://esploradati.istat.it/SDMXWS.
Il pacchetto istatlab fornisce funzioni per accedere
all’API SDMX di ISTAT in modo efficiente. La configurazione del servizio
può essere ottenuta con get_istat_config():
# 1. Ottenere la configurazione del servizio -----
config <- get_istat_config()
# Struttura della configurazione
str(config, max.level = 1)La configurazione include:
-
base_url: URL base del servizio SDMX di ISTAT -
endpoints: endpoint disponibili per l’accesso ai dati e ai metadati -
defaults: impostazioni predefinite (timeout, cache, filtri) -
dataset_categories: categorie organizzate di dataset -
http: configurazione delle richieste HTTP -
cache: impostazioni della cache locale
Gli endpoint principali sono:
# 2. Visualizzare gli endpoint disponibili -----
config$endpoints$rest_v1 # API RESTful v1 (legacy)
config$endpoints$rest_v2 # API RESTful v2
config$endpoints$data # Endpoint per il download dei dati
config$endpoints$dataflow # Elenco dei dataset disponibili
config$endpoints$datastructure # Struttura dei dataset e codelists
config$endpoints$codelist # Definizioni delle codelists
config$endpoints$registry # Endpoint registry SDMX v2.1
config$endpoints$availableconstraint # Valori disponibili per le dimensioniLe impostazioni predefinite includono:
# 3. Impostazioni predefinite -----
config$defaults$timeout # Timeout richieste HTTP (240 secondi)
config$defaults$cache_days # Durata cache metadati (14 giorni)
config$defaults$cache_dir # Directory cache locale ("meta")
config$defaults$test_dataset # Dataset per test di connettività ("534_50")2. Struttura degli endpoint
Il pacchetto istatlab utilizza la funzione
build_istat_url() per costruire URL conformi allo standard
SDMX. Questa funzione gestisce automaticamente i parametri necessari per
ciascun endpoint.
Endpoint data
L’endpoint data viene utilizzato per scaricare i dati da un dataset specifico:
# 1. URL per il download dei dati -----
url <- build_istat_url(
endpoint = "data",
dataset_id = "534_50",
start_time = "2020"
)
print(url)
# Con intervallo temporale completo
url <- build_istat_url(
endpoint = "data",
dataset_id = "534_50",
start_time = "2020",
end_time = "2023"
)
print(url)
# Con filtro personalizzato
url <- build_istat_url(
endpoint = "data",
dataset_id = "534_50",
filter = "A.IT", # Frequenza annuale, Italia
start_time = "2020"
)
print(url)Endpoint dataflow
L’endpoint dataflow restituisce l’elenco di tutti i dataset disponibili:
# 2. URL per l'elenco dei dataset -----
url <- build_istat_url(endpoint = "dataflow")
print(url)Endpoint datastructure
L’endpoint datastructure fornisce la struttura di un dataset, incluse le dimensioni e le codelists:
# 3. URL per la struttura di un dataset -----
url <- build_istat_url(
endpoint = "datastructure",
dsd_ref = "DSD_534_50"
)
print(url)Endpoint codelist
L’endpoint codelist restituisce le definizioni delle codelists:
# 4. URL per le definizioni delle codelists -----
url <- build_istat_url(endpoint = "codelist")
print(url)Parametri di query
L’API SDMX supporta vari parametri di query per filtrare e limitare i dati:
# 5. Parametri di query avanzati -----
# Limitare il numero di osservazioni
url <- build_istat_url(
endpoint = "data",
dataset_id = "534_50",
lastNObservations = 10
)
# Filtrare per data di aggiornamento
timestamp <- as.POSIXct("2025-12-10 14:30:00", tz = "UTC")
url <- build_istat_url(
endpoint = "data",
dataset_id = "534_50",
updated_after = timestamp
)
print(url)Elenco completo degli endpoint
La funzione list_istat_endpoints() restituisce
informazioni su tutti gli endpoint disponibili:
# 6. Visualizzare tutti gli endpoint -----
endpoints <- list_istat_endpoints()
print(endpoints)3. Verifica della connettività
Prima di iniziare a scaricare dati, è opportuno verificare la
connettività al servizio SDMX. La funzione
test_endpoint_connectivity() esegue test di connessione
agli endpoint.
Test di un singolo endpoint
# 1. Testare l'endpoint data -----
result <- test_endpoint_connectivity(
endpoints = "data",
verbose = TRUE
)
print(result)Il risultato include:
-
endpoint: nome dell’endpoint testato -
url: URL completo dell’endpoint -
accessible: logico che indica se l’endpoint è raggiungibile -
status_code: codice HTTP della risposta -
response_time: tempo di risposta in secondi -
error_message: messaggio di errore eventuale
Test di tutti gli endpoint
# 2. Testare tutti gli endpoint -----
all_endpoints <- c(
"data",
"dataflow",
"datastructure",
"codelist",
"registry",
"availableconstraint"
)
results <- test_endpoint_connectivity(
endpoints = all_endpoints,
timeout = 30,
verbose = TRUE
)
# Verificare quali endpoint sono accessibili
accessible_endpoints <- results[results$accessible == TRUE, ]
print(accessible_endpoints)Interpretazione dei risultati
I codici di stato HTTP più comuni sono:
-
200: richiesta riuscita -
404: risorsa non trovata -
500: errore interno del server -
503: servizio temporaneamente non disponibile -
NA: errore di connessione (timeout, rete, firewall)
Risoluzione dei problemi
In caso di problemi di connettività:
# 3. Diagnostica della connettività -----
# Verificare la connessione di rete
if (!results$accessible[results$endpoint == "data"]) {
cat("Possibili cause:\n")
cat("- Connessione Internet assente\n")
cat("- Firewall aziendale che blocca l'accesso\n")
cat("- Configurazione proxy non corretta\n")
cat("- Servizio ISTAT temporaneamente non disponibile\n")
}
# Aumentare il timeout per connessioni lente
results_slow <- test_endpoint_connectivity(
endpoints = "data",
timeout = 60,
verbose = TRUE
)4. Catalogo dei dataset
ISTAT pubblica centinaia di dataset attraverso l’API SDMX. Il
pacchetto istatlab fornisce funzioni per esplorare il
catalogo e trovare i dataset di interesse.
Download del catalogo completo
La funzione download_metadata() scarica l’elenco
completo dei dataset disponibili. I metadati vengono memorizzati nella
cache locale e aggiornati automaticamente ogni 14 giorni:
# 1. Scaricare il catalogo dei dataset -----
catalogo <- download_metadata()
data.table::setDT(catalogo)
# Visualizzare la struttura
str(catalogo)
# Prime righe del catalogo
head(catalogo[, .(id, Name.it, Name.en)])Il catalogo include:
-
id: identificatore univoco del dataset -
Name.it: nome del dataset in italiano -
Name.en: nome del dataset in inglese - Altri campi descrittivi
Cache dei metadati
I metadati vengono salvati nella directory meta/ della
directory di lavoro:
# 2. Verifica della cache -----
config <- get_istat_config()
# File della cache
cache_file <- file.path(
config$defaults$cache_dir,
config$cache$metadata_file
)
print(cache_file)
# La cache viene aggiornata automaticamente dopo 14 giorni
# Per forzare l'aggiornamento, eliminare il file della cacheRicerca per parole chiave
La funzione search_dataflows() permette di cercare
dataset per parole chiave in italiano e inglese:
# 3. Ricerca di dataset -----
# Ricerca in italiano
occupati <- search_dataflows("occupati")
print(occupati[, .(id, Name.it)])
# Ricerca in inglese
vacancy <- search_dataflows("vacancy")
print(vacancy[, .(id, Name.en)])
# Ricerca multipla (OR logico)
lavoro <- search_dataflows(c("lavoro", "employment", "occupazione"))
print(lavoro[, .(id, Name.it, Name.en)])
# Ricerca solo negli identificatori
dataset_534 <- search_dataflows("534", fields = "id")
print(dataset_534[, .(id, Name.it)])Dataset correlati
La funzione expand_dataset_ids() trova dataset correlati
(base e sotto-dataset):
# 4. Trovare dataset correlati -----
correlati <- expand_dataset_ids("150_908")
print(correlati)
# Esempio: 150_908, 150_915, 150_916 sono dataset correlati
# sull'occupazione (mensile, trimestrale, annuale)Dataset organizzati per categoria
Il pacchetto organizza i dataset più comuni in categorie:
# 5. Dataset per categoria -----
# Tutte le categorie disponibili
tutte_categorie <- get_categorized_datasets()
str(tutte_categorie)
# Dataset di una categoria specifica
employment_ids <- get_dataset_category("employment")
print(employment_ids)
unemployment_ids <- get_dataset_category("unemployment")
print(unemployment_ids)
job_vacancies_ids <- get_dataset_category("job_vacancies")
print(job_vacancies_ids)
labour_force_ids <- get_dataset_category("labour_force")
print(labour_force_ids)5. Esplorare la struttura di un dataset
Prima di scaricare i dati, è utile conoscere la struttura del dataset, le dimensioni disponibili e i valori delle codelists.
Dimensioni del dataset
La funzione get_dataset_dimensions() restituisce i nomi
delle dimensioni:
# 1. Ottenere le dimensioni -----
dimensioni <- get_dataset_dimensions("150_908")
print(dimensioni)
# Esempio di output: FREQ, ITTER107, SESSO, ETA1, TIPO_DATO, etc.Codelists
Le codelists contengono i valori possibili per ciascuna dimensione.
La funzione download_codelists() scarica tutte le codelists
per un dataset:
# 2. Scaricare le codelists -----
codelists <- download_codelists("150_908")
# Struttura: lista nominata di data.table
names(codelists)
# Esempio: codelist ITTER107 (territorio)
head(codelists[["ITTER107"]])
# Esempio: codelist SESSO (genere)
print(codelists[["SESSO"]])
# Esempio: codelist ETA1 (classi di età)
print(codelists[["ETA1"]])Ogni codelist è un data.table con colonne:
-
id: codice identificativo -
name: descrizione testuale
Funzioni alternative per le codelists
# 3. Funzioni alternative -----
# get_dataset_codelists: alias di download_codelists
codelists_alt <- get_dataset_codelists("150_908")
identical(codelists, codelists_alt)
# ensure_codelists: verifica che le codelists siano in cache
ensure_codelists("150_908")
# Questa funzione scarica le codelists solo se non sono già presentiDimensioni dal registry
La funzione fetch_registry_dimensions() utilizza
l’endpoint registry per ottenere informazioni sulle dimensioni:
# 4. Dimensioni dal registry API -----
dim_registry <- fetch_registry_dimensions("150_908")
print(dim_registry)
# Questa funzione è equivalente a get_dataset_dimensions
# ma utilizza esplicitamente l'endpoint registryIspezionare una codelist
Una volta scaricate le codelists, è possibile ispezionarle nel dettaglio:
# 5. Ispezionare una codelist specifica -----
codelists <- download_codelists("534_50")
# Codelist ITTER107 (territorio)
territorio <- codelists[["ITTER107"]]
print(territorio)
# Filtrare per regioni
regioni <- territorio[grepl("^IT[A-Z]", id)]
print(regioni)
# Codelist FREQ (frequenza)
frequenze <- codelists[["FREQ"]]
print(frequenze)
# M = mensile, Q = trimestrale, A = annuale6. Download dei dati
Il pacchetto istatlab fornisce funzioni flessibili per
il download dei dati dall’API SDMX di ISTAT.
Download di base
La funzione download_istat_data() scarica i dati da un
dataset specificato:
# 1. Download di base -----
dati <- download_istat_data(
dataset_id = "150_908",
start_time = "2023"
)
# Visualizzare la struttura
str(dati)
head(dati)Parametri principali
La funzione supporta numerosi parametri:
-
dataset_id: identificatore del dataset (obbligatorio) -
filter: filtro dimensionale (default “ALL”) -
start_time: periodo iniziale -
end_time: periodo finale -
incremental: periodo iniziale per download incrementale -
timeout: timeout della richiesta in secondi -
verbose: messaggi diagnostici -
updated_after: timestamp per rilevare aggiornamenti -
return_result: restituire oggettoistat_resultcompleto -
check_update: verificare se ci sono aggiornamenti -
cache_dir: directory della cache -
existing_data: data.table esistente per merge
Download con intervallo temporale
# 2. Download con intervallo temporale -----
dati_range <- download_istat_data(
dataset_id = "150_908",
start_time = "2020",
end_time = "2023"
)
# Verifica dell'intervallo temporale
range(dati_range$TIME_PERIOD)Download incrementale
Il parametro incremental permette di scaricare solo i
dati a partire da una certa data:
# 3. Download incrementale -----
dati_incrementali <- download_istat_data(
dataset_id = "150_908",
incremental = "2024"
)
# Questa modalità è utile per aggiornare dataset già scaricati
# scaricando solo i nuovi datiVerifica aggiornamenti
Il parametro check_update verifica se ci sono
aggiornamenti disponibili prima di scaricare:
# 4. Verifica aggiornamenti -----
dati_update <- download_istat_data(
dataset_id = "534_50",
check_update = TRUE
)
# Se non ci sono aggiornamenti, la funzione restituisce NULL
# senza scaricare i datiMerge con dati esistenti
Il parametro existing_data permette di unire i nuovi
dati con quelli già scaricati:
# 5. Merge con dati esistenti -----
# Prima scarico i dati fino al 2023
dati_vecchi <- download_istat_data(
dataset_id = "534_50",
start_time = "2020",
end_time = "2023"
)
# Poi scarico i dati del 2024 e li unisco
dati_completi <- download_istat_data(
dataset_id = "534_50",
start_time = "2024",
existing_data = dati_vecchi
)
# dati_completi contiene ora tutto il periodo 2020-2024Oggetto risultato completo
Il parametro return_result = TRUE restituisce un oggetto
istat_result con informazioni aggiuntive:
# 6. Oggetto risultato completo -----
risultato <- download_istat_data(
dataset_id = "534_50",
return_result = TRUE
)
# Struttura dell'oggetto istat_result
str(risultato)
# Componenti:
risultato$data # data.table con i dati
risultato$success # logico: download riuscito?
risultato$exit_code # codice di uscita
risultato$md5 # hash MD5 dei dati
risultato$message # messaggio descrittivo
risultato$is_timeout # logico: timeout?Download per frequenza
La funzione download_istat_data_by_freq() separa i dati
per frequenza temporale:
# 7. Download per frequenza -----
# Scaricare tutte le frequenze (separatamente)
dati_freq <- download_istat_data_by_freq(
dataset_id = "151_914",
start_time = "2020"
)
# Risultato: lista nominata con data.table per ogni frequenza
names(dati_freq) # "M", "Q", "A" (mensile, trimestrale, annuale)
# Accedere ai dati mensili
dati_mensili <- dati_freq[["M"]]
head(dati_mensili)
# Accedere ai dati trimestrali
dati_trimestrali <- dati_freq[["Q"]]
head(dati_trimestrali)
# Scaricare solo una frequenza specifica
solo_trimestrale <- download_istat_data_by_freq(
dataset_id = "151_914",
start_time = "2020",
freq = "Q"
)Download multiplo
La funzione download_multiple_datasets() permette di
scaricare più dataset in parallelo:
# 8. Download multiplo -----
# Scaricare più dataset contemporaneamente
ids <- c("534_50", "534_51", "534_52")
dati_multipli <- download_multiple_datasets(
dataset_ids = ids,
start_time = "2020"
)
# Risultato: lista nominata con un data.table per ogni dataset
names(dati_multipli)
# Accedere ai dati di un dataset specifico
dati_50 <- dati_multipli[["534_50"]]
head(dati_50)
# Download multiplo con filtro di aggiornamento
timestamp <- as.POSIXct("2025-01-01 00:00:00", tz = "UTC")
dati_aggiornati <- download_multiple_datasets(
dataset_ids = ids,
updated_after = timestamp
)
# Vengono scaricati solo i dataset aggiornati dopo il timestamp7. Elaborazione dei dati
Dopo il download, i dati vengono restituiti in formato grezzo con codici dimensionali. Il pacchetto fornisce funzioni per trasformare i codici in etichette leggibili.
Applicazione delle etichette
La funzione apply_labels() trasforma i codici
dimensionali in etichette descrittive:
# 1. Applicare le etichette -----
# Scaricare dati grezzi
dati_raw <- download_istat_data(
dataset_id = "150_908",
start_time = "2023"
)
# Prima: colonne con codici (ITTER107, SESSO, ETA1, etc.)
head(dati_raw)
# Applicare le etichette
dati_labeled <- apply_labels(dati_raw)
# Dopo: colonne con codici + colonne con etichette
head(dati_labeled)La funzione apply_labels() crea:
- Colonna
tempo: data convertita da TIME_PERIOD - Colonna
valore: valore numerico da OBS_VALUE - Colonne
*_label: etichette descrittive per ogni dimensione (es.ITTER107_label,SESSO_label) - Mantiene tutte le colonne originali
Filtro temporale
La funzione filter_by_time() filtra i dati per
intervallo temporale:
# 2. Filtrare per periodo -----
# Filtrare per anno
dati_2024 <- filter_by_time(
dati_labeled,
start_date = "2024-01-01"
)
# Filtrare per intervallo
dati_range <- filter_by_time(
dati_labeled,
start_date = "2023-01-01",
end_date = "2023-12-31"
)
# Specificare la colonna temporale (se diversa da "tempo")
dati_custom <- filter_by_time(
dati_labeled,
start_date = "2024-01-01",
time_col = "TIME_PERIOD"
)Validazione dei dati
La funzione validate_istat_data() verifica la qualità e
la struttura dei dati:
# 3. Validare i dati -----
validazione <- validate_istat_data(dati_labeled)
# Restituisce un oggetto con informazioni diagnostiche
str(validazione)
# Verifica:
# - Presenza di colonne obbligatorie
# - Valori mancanti
# - Duplicati
# - Consistenza dei tipi di datoNormalizzazione dei nomi delle variabili
La funzione clean_variable_names() normalizza i nomi
delle colonne:
# 4. Normalizzare i nomi delle colonne -----
dati_clean <- clean_variable_names(dati_labeled)
# Rimuove caratteri speciali, converte in minuscolo,
# sostituisce spazi con underscore
names(dati_clean)8. Formati di risposta e gestione errori
L’API SDMX di ISTAT supporta diversi formati di risposta. Il
pacchetto istatlab utilizza il formato CSV per
efficienza.
Formato CSV
Il formato CSV viene richiesto tramite l’header HTTP:
# 1. Configurazione del formato -----
config <- get_istat_config()
# Header per richiesta CSV
print(config$http$accept_csv)
# "application/vnd.sdmx.data+csv;version=1.0.0"
# Header per richiesta XML (alternativa)
print(config$http$accept_xml)
# "application/vnd.sdmx.structurespecificdata+xml;version=2.1"Oggetto istat_result
L’oggetto istat_result restituito da
download_istat_data(return_result = TRUE) contiene:
# 2. Componenti dell'oggetto istat_result -----
risultato <- download_istat_data(
dataset_id = "534_50",
return_result = TRUE
)
# data: data.table con i dati scaricati
dati <- risultato$data
class(dati) # "data.table" "data.frame"
# success: logico che indica successo del download
risultato$success # TRUE o FALSE
# exit_code: codice numerico dello stato
# 0 = successo, 1 = errore, 2 = timeout, 3 = nessun aggiornamento
risultato$exit_code
# md5: hash MD5 dei dati (per verifica integrità)
risultato$md5
# message: messaggio descrittivo
risultato$message
# is_timeout: logico che indica timeout
risultato$is_timeoutCodici di errore HTTP
I codici HTTP più comuni e il loro significato:
# 3. Interpretazione dei codici di stato -----
# 200: richiesta riuscita
# 404: dataset non trovato
if (risultato$exit_code == 1) {
cat("Errore: verificare che il dataset_id sia corretto\n")
}
# 500: errore interno del server ISTAT
# 503: servizio temporaneamente non disponibile
if (risultato$exit_code == 1) {
cat("Errore del server: riprovare più tardi\n")
}
# Timeout: richiesta scaduta
if (risultato$is_timeout) {
cat("Timeout: aumentare il parametro timeout\n")
}Gestione degli errori
Esempio di gestione errori con tryCatch():
# 4. Gestione errori con tryCatch -----
dati <- tryCatch(
{
download_istat_data(
dataset_id = "150_908",
start_time = "2020",
timeout = 120
)
},
error = function(e) {
cat("Errore nel download:\n")
cat(conditionMessage(e), "\n")
return(NULL)
},
warning = function(w) {
cat("Avviso:\n")
cat(conditionMessage(w), "\n")
}
)
# Verificare il risultato
if (is.null(dati)) {
cat("Download fallito\n")
} else {
cat("Download riuscito:", nrow(dati), "righe\n")
}Gestione programmatica con return_result
Utilizzare return_result = TRUE per gestione
programmatica degli errori:
# 5. Gestione programmatica -----
risultato <- download_istat_data(
dataset_id = "150_908",
start_time = "2020",
return_result = TRUE
)
# Verifica del successo
if (risultato$success) {
# Download riuscito
dati <- risultato$data
cat("Scaricate", nrow(dati), "righe\n")
cat("Hash MD5:", risultato$md5, "\n")
} else {
# Download fallito
cat("Errore:", risultato$message, "\n")
# Gestione per tipo di errore
if (risultato$is_timeout) {
cat("Suggerimento: aumentare il timeout\n")
} else if (risultato$exit_code == 3) {
cat("Nessun aggiornamento disponibile\n")
} else {
cat("Verificare dataset_id e connessione\n")
}
}9. Risorse aggiuntive
Dataset comuni
Tabella dei dataset più utilizzati per i dati statistici italiani:
| Dataset ID | Descrizione | Frequenza |
|---|---|---|
| 150_908 | Dati mensili sull’occupazione | Mensile |
| 150_915 | Statistiche trimestrali sull’occupazione | Trimestrale |
| 151_914 | Tassi di disoccupazione | Mensile/Trimestrale |
| 534_50 | Posti vacanti | Trimestrale |
| 534_51 | Posti vacanti per settore | Trimestrale |
| 534_52 | Posti vacanti per regione | Trimestrale |
| 152_914 | Forze di lavoro | Mensile/Trimestrale |
| 152_915 | Forze di lavoro per regione | Trimestrale |
Esempi di utilizzo
# 1. Download dataset comuni -----
# Occupazione mensile
occupazione <- download_istat_data(
dataset_id = "150_908",
start_time = "2023"
)
dati_occ <- apply_labels(occupazione)
# Disoccupazione trimestrale
disoccupazione <- download_istat_data_by_freq(
dataset_id = "151_914",
start_time = "2023",
freq = "Q"
)
# Posti vacanti
vacancy <- download_istat_data(
dataset_id = "534_50",
start_time = "2020"
)
dati_vac <- apply_labels(vacancy)Link utili
- Catalogo SDMX ISTAT: https://esploradati.istat.it/databrowser/
- Documentazione SDMX: https://sdmx.org/
- Standard ISO 17369: https://www.iso.org/standard/52500.html
- Repository GitHub istatlab: https://github.com/gmontaletti/istatlab
- Segnalazione problemi: https://github.com/gmontaletti/istatlab/issues
Altre vignette
Per approfondire l’utilizzo del pacchetto, consultare le altre vignette:
-
getting-started-it: guida introduttiva al pacchetto istatlab -
gestione-dati-it: elaborazione e analisi dei dati scaricati
Supporto
Per domande, suggerimenti o segnalazioni:
- Email: giampaolo.montaletti@gmail.com
- GitHub Issues: https://github.com/gmontaletti/istatlab/issues
- ORCID: https://orcid.org/0009-0002-5327-1122