istacrEn este documento se estudia cómo explorar los datasets del
ISTAC usando la librería istacr.
istacrLeemos los datos básicos de los datasets existentes y recopilamos en el tibble ISTAC_datasets la información básica
# LECTURA INFORMACIÓN BÁSICA DATASETS ACCESIBLES A TRAVÉS DE istacr
ISTAC_INDICATORS <- istacr::get_indicators(limit=1000)
# RECOPILACIÓN INFORMACIÓN BÁSICA EN EL TIBBLE ISTAC_datasets
ISTAC_datasets <- tibble(
id=as.character(),
title=as.character(),
description=as.character(),
notes=as.character(),
subject=as.character()
)
for(k in 1:length(ISTAC_INDICATORS$items$id)){
ISTAC_datasets <- ISTAC_datasets |>
add_row(
id=ISTAC_INDICATORS$items$id[k],
title=ISTAC_INDICATORS$items$title$es[k],
description=ISTAC_INDICATORS$items$conceptDescription$es[k],
notes=ISTAC_INDICATORS$items$notes$es[k],
subject=ISTAC_INDICATORS$items$subjectTitle$es[k]
)
}
ISTAC_datasets <- ISTAC_datasets |>
arrange(subject,id)
Añadimos el nº observaciones (filas) de cada dataset, el número de
regiones distintas utilizadas, la frecuencia de los datos
(Y anual, S semestral, Q
trimestral, M mensual, W semanal,
D diaria, y ? si el formato de fecha no se
reconoce), el periodo en años que cubre y detectamos si los datasets
tienen datos de municipios de las islas.
deteccion_area_geografica <- function(u){
if(any(c("38005","35012","38027") %in% u)) return("MUNI")
if(any(c("ES705","ES706","ES708") %in% u)) return("ISLA")
if(any(c("ES11","ES51","ES30") %in% u)) return("CCAA")
if(any(c("ES213","ES425","ES701") %in% u)) return("PROV")
if(length(u) == 1 && "ES70" %in% u) return("CANA")
return("OTRO")
}
# Detecta la frecuencia de una serie a partir del FORMATO de sus fechas.
# Muchos datasets mezclan el agregado anual ("1999") con el detalle
# ("1999-Q1"), así que se descartan los valores de 4 caracteres y se devuelve
# la granularidad más fina que aparezca.
# Se compara con patrones explícitos en vez de restar dígitos de la fecha:
# "2026-Q1"/"2026-Q2" y "2026-01"/"2026-02" son indistinguibles si uno se fija
# solo en el carácter de la posición 7 (en ambos casos pasa de 1 a 2), y por eso
# las series trimestrales se etiquetaban como mensuales.
deteccion_frecuencia <- function(fechas){
d <- unique(fechas[!is.na(fechas)])
if(!length(d)) return(NA_character_)
d <- d[nchar(d) > 4]
if(!length(d)) return("Y") # solo agregados anuales
if(any(grepl("^\\d{4}-\\d{2}-\\d{2}$", d))) return("D")
if(any(grepl("^\\d{4}-W\\d{1,2}$", d))) return("W")
if(any(grepl("^\\d{4}-M?(0[1-9]|1[0-2])$", d))) return("M")
if(any(grepl("^\\d{4}-Q[1-4]$", d))) return("Q")
if(any(grepl("^\\d{4}-S[1-2]$", d))) return("S")
return("?") # formato no previsto: se marca, no se adivina
}
# --- CONTROL DE CUELGUES ----------------------------------------------------
# El recorrido son cientos de llamadas a la API del ISTAC y puede quedarse
# esperando indefinidamente en una de ellas. Dos medidas:
#
# 1) Se acota el tiempo de cada llamada, para que una petición colgada termine
# en error en vez de bloquear el documento entero.
# 2) Se deja constancia del avance en un fichero .log con marca de tiempo. Al
# compilar con quiet=TRUE no se ve NADA por consola -los print(id) van al
# documento, que no existe hasta el final-, así que sin este log no hay forma
# de saber si el proceso avanza o está colgado. El fichero se puede abrir
# mientras compila: la última línea dice por qué dataset va y cuánto tardó.
#
# NOTA: no se capturan los errores para saltarse el dataset. Si uno falla, el
# documento se detiene y se relanza la compilación: se prefiere ir despacio a
# perder datasets del catálogo sin enterarse.
options(timeout = 60)
if(requireNamespace("httr", quietly = TRUE)){
httr::set_config(httr::timeout(60))
}
LOG <- "ISTAC_TableDatasetGeneration.log"
cat(format(Sys.time()), "- inicio del recorrido\n", file = LOG)
log_avance <- function(k, n, id, seg, nota = ""){
cat(sprintf("%s %4d/%4d %-38s %6.1f s%s%s\n",
format(Sys.time()), k, n, as.character(id), seg,
if(seg > 30) " <-- LENTO" else "",
if(nzchar(nota)) paste0(" ", nota) else ""),
file = LOG, append = TRUE)
}
cat("ISTAC_datasets tiene", nrow(ISTAC_datasets), "filas\n")
## ISTAC_datasets tiene 400 filas
GEOGRAPHICAL_LISTADO <- as.character()
n.obs <- as.numeric()
n.reg <- as.numeric()
freq <- as.character()
initDate <- as.character()
lastDate <- as.character()
area <- as.character()
for(id in ISTAC_datasets$id){
#print(id)
t.inicio <- Sys.time()
tb <- istacr::get_indicators_code_data(id)$dataframe
if (! "ABSOLUTE" %in% tb$MEASURE) stop("El campo 'ABSOLUTE' no existe en el tibble")
n.obs <- c(n.obs,nrow(tb))
AREAid <- unique(tb$GEOGRAPHICAL)
n.reg <- c(n.reg,length(AREAid))
area <- c(area, deteccion_area_geografica(AREAid))
dates <- tb |> pull(TIME) |> unique() |> sort()
#initDate <- c(initDate,paste0(substr(dates[1],1,4),"-",substr(dates[length(dates)],1,4)))
initDate <- c(initDate,min(dates))
lastDate <- c(lastDate,max(dates))
freq <- c(freq,deteccion_frecuencia(dates))
log_avance(which(ISTAC_datasets$id == id)[1], nrow(ISTAC_datasets), id,
as.numeric(difftime(Sys.time(), t.inicio, units = "secs")),
paste0("freq=", tail(freq,1), " n.obs=", tail(n.obs,1)))
}
# GEOGRAPHICAL_LISTADO |>
# as_tibble() |>
# write_csv("ISTAC_AREAS_GEOGRAFICAS_LISTADO.csv")
ISTAC_datasets <- ISTAC_datasets |>
mutate(freq = freq) |>
relocate(freq,.after=title) |>
mutate(initDate = initDate) |>
relocate(initDate,.after=title) |>
mutate(lastDate = lastDate) |>
relocate(lastDate,.after=initDate) |>
mutate(n.obs = n.obs) |>
relocate(n.obs,.after=title) |>
mutate(n.reg = n.reg) |>
relocate(n.reg,.after=title) |>
mutate(area = area) |>
relocate(area,.after=title)
ISTAC_datasets |>
select(id,subject,n.reg,n.obs,area,freq,initDate,lastDate) |>
mutate(`Nº` = row_number(), .before = 1) |>
knitr::kable()
Escribimos los datasets detectados en una hoja excel
ISTAC_datasets |>
select(id,subject,n.reg,n.obs,area,freq,initDate,lastDate) |>
mutate(`Nº` = row_number(), .before = 1) |>
write.xlsx("ISTAC_datasets.xlsx")