<!--
Análisis del dataset "Variables climáticas por municipio de Canarias (AdapteCCa)", generado por CLIMA_CANARIAS_DatasetSelection.Rmd el 2026-10-08.
Se incluye en la sección "Comprensión de los datos" de la memoria con este código, en un
chunk con las opciones results='asis' y cache=FALSE:

    clima <- aedv_incluir_dataset("CLIMA_CANARIAS_analisis.Rmd")
    # este dataset tiene 2 tablas: aedv_incluir_dataset() las devuelve en una lista
    clima_obs  <- clima$data  # observaciones mensuales por municipio, 1990-2022
    clima_proy <- clima$proy  # proyecciones por escenario, modelo y horizonte

No conviene editar este fichero: el texto explicativo del dataset se escribe en la memoria,
antes o después del chunk que lo incluye.
-->

### Variables climáticas por municipio de Canarias (AdapteCCa)

```{r}
# nombres con los que se guardaron los ficheros del dataset
filename <- "CLIMA_CANARIAS"
f_obs    <- "observaciones_canarias_1990_2022.rds"
f_proy   <- "proyecciones_canarias.rds"

# tablas que devuelve aedv_incluir_dataset() al incluir este análisis en la memoria
tablas_exportadas <- c("data", "proy")
```

```{r}
# las explicaciones de los indicadores viven en las hojas `variables`,
# `horizontes` y `escenarios` del fichero de metadatos; la ficha general en `dataset`
ficha          <- read.xlsx(paste0(filename, "_metadatos.xlsx"), sheet = "dataset")
variables_sel  <- read.xlsx(paste0(filename, "_metadatos.xlsx"), sheet = "variables")
desc_horizonte <- read.xlsx(paste0(filename, "_metadatos.xlsx"), sheet = "horizontes")
desc_escenario <- read.xlsx(paste0(filename, "_metadatos.xlsx"), sheet = "escenarios")

# las variables a analizar salen de los propios metadatos: así esta sección no
# depende del vector VARS definido en la sección anterior
VARS <- variables_sel$variable
```

**metadatos**

<div class="tabla-scroll">

```{r}
knitr::kable(ficha)
```

</div>

#### Origen de los datos: AdapteCCa

Todos los datos provienen del **Visor de Escenarios de Cambio Climático de
AdapteCCa**, la plataforma oficial sobre adaptación al cambio climático en España.
Pertenecen a la colección **Escenarios-PNACC** (Plan Nacional de Adaptación al
Cambio Climático) y los elabora el Grupo de Trabajo de Escenarios: la **Oficina
Española de Cambio Climático (OECC/MITECO)**, la **AEMET**, el **CSIC** y la
**Fundación Biodiversidad**, con desarrollo técnico de la **Universidad de
Cantabria (IFCA, CSIC-UC)** y **Predictia**. Los datos se distribuyen en formato
NetCDF mediante un servicio **THREDDS**.

Para Canarias, AdapteCCa ofrece —por primera vez en su última actualización—
datos **en rejilla de alta resolución (~2,5 km)**, tanto observados como
proyectados, sobre la malla observacional **ROCIO+\_CAN** de AEMET (antes solo
había datos puntuales por estación). Hay dos productos bien distintos:

##### Observaciones: el clima registrado (1990–2022)

Es el clima **realmente medido**, sin ningún modelo climático de por medio:

- Parte de las **observaciones diarias de las estaciones de AEMET** en Canarias.
- Esos registros se **interpolan a una rejilla regular de ~2,5 km**
  (producto AEMET-2.5KM / ROCIO+_CAN), que cubre todo el archipiélago, también
  donde no hay estaciones.
- De la rejilla diaria se calculan los **agregados mensuales** que usamos (medias
  de temperatura, totales de precipitación, conteos de días, máximos…).
- La serie en rejilla disponible cubre **1990–2022**.

Es, por tanto, dato observado y espacializado: sirve como **línea base** real
contra la que comparar el futuro.

##### Proyecciones: el clima simulado (siglo XXI)

Es el clima **simulado** para el futuro, y su obtención tiene dos pasos:

1. **Modelos climáticos globales CMIP6** — los mismos que sustentan el 6º Informe
   del IPCC (AR6). Simulan el clima del planeta para distintos escenarios de
   emisiones, pero con una resolución demasiado gruesa (~100 km) para unas islas
   pequeñas.
2. **Regionalización (downscaling) estadística** — se "baja" esa información a la
   rejilla de ~2,5 km con técnicas de *machine learning* que aprenden la relación
   entre el clima global y las observaciones de AEMET. Se usan **dos métodos**
   según la variable:
   - **ESD-RegBA** (desarrollado por AEMET) → variables de **temperatura**.
   - **deepESD** (desarrollado por el CSIC, basado en *deep learning*) →
     **precipitación** (y evapotranspiración).

El resultado son **climatologías** (medias de 30 años, no series con fecha) para
los **4 escenarios de emisión SSP** × **4 horizontes**: la base histórica de
referencia (**1971–2000**) y los 3 horizontes futuros (2011–2040, 2041–2070,
2071–2100), calibradas con las observaciones de AEMET. El detalle de escenarios y
horizontes está más abajo, en las secciones *Proyecciones* y *Escenarios de emisión (GHG / SSP)*.

#### Variables (datasets) seleccionadas

<div class="tabla-scroll-xy con-desc">

```{r}
# kable en vez de DT::datatable: aquí solo hace falta poder recorrer la tabla, no
# filtrarla ni ordenarla. El contenedor .tabla-scroll-xy le da el scroll en los
# dos ejes, con la cabecera fija arriba, y .con-desc deja que la última columna
# (la descripción) reparta en varias líneas
variables_sel |>
  knitr::kable(col.names = c("variable", "categoría", "unidad", "área",
                             "frecuencia", "descripción"))
```

</div>

#### Datos: serie histórica observada

```{r}
# Carga del histórico observado (dataset ya generado)
hist <- readRDS(f_obs) |>
  as_tibble() |>
  filter(variable %in% VARS)

# Estructura comparable a la del análisis del ISTAC:
#   variable (= indicador/atributo) · municipio (= región) · fecha (= TIME) · value
data <- hist |>
  transmute(VARIABLE = variable,
            MUNICIPIO = municipio,
            UNIDAD = unidad,
            TIME = fecha,
            VALUE = value) |>
  arrange(VARIABLE, MUNICIPIO, TIME)
```

**data**

```{r}
data |> print(n=5)
```

Muestra de las primeras 20 filas del histórico observado por municipio, variable y mes:

<div class="tabla-scroll">

```{r}
data |> slice(1:20) |> knitr::kable()
```

</div>

#### Análisis de series temporales por variable

> Para que una variable **cumpla el criterio de rango temporal**, el valor de
> **P25** debe superar el umbral mínimo según la frecuencia: **≥ 10** para datos
> anuales (`Y`), **≥ 40** para trimestrales (`Q`) y **≥ 60** para mensuales
> (`M`). El percentil 25 (P25) es el tamaño de serie que supera el 75 % de los
> municipios: si P25 ≥ umbral, al menos el 75 % de los municipios cumple el rango
> temporal mínimo, que es el requisito de AEDV.

```{r}
classify_time <- function(t) {
  dplyr::case_when(
    stringr::str_detect(t, "^[0-9]{4}M[0-9]{2}$|^[0-9]{4}-[0-9]{2}$") ~ "M",
    stringr::str_detect(t, "^[0-9]{4}[QT][0-9]$") ~ "Q",
    stringr::str_detect(t, "^[0-9]{4}$")          ~ "Y",
    TRUE                                          ~ "otro"
  )
}

tb_series <- data |>
  mutate(freq_obs = classify_time(TIME)) |>
  group_by(VARIABLE, MUNICIPIO, freq_obs) |>
  summarise(
    n_periodos = n_distinct(TIME),
    date_min   = min(TIME),
    date_max   = max(TIME),
    .groups    = "drop"
  ) |>
  group_by(VARIABLE, freq_obs) |>
  summarise(
    n_regiones = n_distinct(MUNICIPIO),
    date_start = min(date_min),
    date_end   = max(date_max),
    P0   = as.integer(min(n_periodos)),
    P25  = as.integer(quantile(n_periodos, 0.25)),
    P50  = as.integer(quantile(n_periodos, 0.50)),
    P75  = as.integer(quantile(n_periodos, 0.75)),
    P100 = as.integer(max(n_periodos)),
    .groups = "drop"
  ) |>
  left_join(variables_sel |> select(variable, categoria),
            by = c("VARIABLE" = "variable")) |>
  relocate(categoria, .after = VARIABLE) |>
  relocate(freq_obs, .after = categoria)
```

**Por variable**: nº de municipios, rango de fechas y percentiles del tamaño de
serie temporal (periodos por municipio).

<div class="tabla-scroll-xy">

```{r}
knitr::kable(tb_series)
```

</div>

#### Municipios y número de observaciones

<div class="tabla-scroll-xy">

```{r}
# son 88 municipios: se muestran TODOS y se recorren con el scroll del
# contenedor, con la cabecera fija arriba
data |>
  group_by(MUNICIPIO) |>
  summarise(n_obs = n(), .groups = "drop") |>
  arrange(MUNICIPIO) |>
  knitr::kable()
```

</div>

<!-- INICIO DE LA VALIDACIÓN AEDV -->

#### Validación de requisitos AEDV

```{r}
umbral_freq <- c(Y = 10L, Q = 40L, M = 60L, otro = NA_integer_)
anio_min    <- 2024L   # requisito AEDV "datos actualizados" (último dato ≥ anio_min)

tb_val <- tb_series |>
  mutate(
    umbral   = umbral_freq[freq_obs],
    year_end = as.integer(substr(date_end, 1, 4)),
    ok_cob   = n_regiones > 80,                 # nivel municipio (MUNI)
    ok_fecha = year_end >= anio_min,
    ok_temp  = !is.na(umbral) & P25 >= umbral,
    ok_total = ok_cob & ok_fecha & ok_temp,
    etiqueta = paste0(VARIABLE, " [", freq_obs, "]")
  )
```

**Validación de requisitos AEDV** — umbrales: > 80 municipios, último dato ≥
`r anio_min`, P25 ≥ 60 meses.

<div class="tabla-scroll-xy">

```{r}
# Tabla de validación en HTML (antes era un heatmap de ggplot, pero al ser una
# IMAGEN su altura crecía con el nº de variables). Como tabla se muestran TODAS
# las filas y se recorren con el scroll del contenedor, con la cabecera fija
# arriba. Las clases val-ok/val-no dan el color a cada celda.
marca <- function(x)
  ifelse(x, '<span class="val-ok">&#10004;</span>', '<span class="val-no">&#10008;</span>')

tb_val |>
  transmute(
    Variable                        = etiqueta,
    `Cobertura geográfica`          = marca(ok_cob),
    `Datos actualizados (≥ 2024)`   = marca(ok_fecha),
    `Tamaño series (P25 ≥ umbral)`  = marca(ok_temp),
    `CUMPLE LOS 3`                  = marca(ok_total)
  ) |>
  # escape = FALSE para que el <span> de cada celda se interprete como HTML y
  # no se imprima literalmente
  knitr::kable(escape = FALSE, align = c("l", rep("c", 4)))
```

</div>

```{r}
n_total   <- n_distinct(tb_val$VARIABLE)
n_cob     <- sum(tb_val$ok_cob)
n_temp    <- sum(tb_val$ok_temp)
n_fecha   <- sum(tb_val$ok_fecha)
n_validos <- tb_val |>
  group_by(VARIABLE) |>
  summarise(valido = any(ok_total), .groups = "drop") |>
  pull(valido) |> sum()
```

De las **`r n_total`** variables seleccionadas: **`r n_cob`** cumplen la
**cobertura geográfica** (> 80 municipios), **`r n_temp`** el **tamaño de serie
temporal** (P25 ≥ 60 meses) y **`r n_fecha`** la **actualización** (último dato ≥
`r anio_min`).

> **Limitación de la fuente (importante para la conclusión):** el producto
> observado en rejilla de AdapteCCa llega hasta **2022** (es una colección por
> versión —Escenarios-PNACC 2024—, no una serie que se actualice cada año). Por
> eso, con el umbral estricto `anio_min = 2024` el criterio de "datos
> actualizados" **no se cumple** para ninguna variable; sin embargo, dado que la cobertura y
> la longitud temporal son excelentes (88 municipios, 396 meses por municipio,
> 1990–2022), podremos usar este dataset para el proyecto personal de AEDV.


<!-- FIN DE LA VALIDACIÓN AEDV -->

#### Proyecciones (proyecciones_canarias.rds)

```{r}
# el dataset de proyecciones se lee UNA sola vez y se reutiliza en todo lo que sigue
proy <- readRDS(f_proy) |> as_tibble()
```

El segundo dataset, `proyecciones_canarias.rds`, es el **complemento prospectivo**
del histórico: las mismas 14 variables, pero proyectadas al futuro con modelos
CMIP6 regionalizados. Se diferencia del histórico en su estructura temporal:

- **No tiene serie anual ni fechas**: son **climatologías** (un valor por mes),
  así que la dimensión temporal son los 12 meses, no años. Cada valor es la
  **media climatológica de 30 años** del horizonte correspondiente.
- Añade tres dimensiones: **`escenario`** (4 trayectorias de emisión
  SSP: `ssp126`, `ssp245`, `ssp370`, `ssp585`), **`modelo`** (los 11 GCMs de CMIP6
  individuales más `ensemble`, la media del conjunto) y **`horizonte`** (4 ventanas
  climáticas de 30 años: la base histórica de referencia y 3 horizontes futuros).
- Columnas: `municipio · variable · unidad · escenario · modelo · horizonte · mes · value`.

Los **horizontes** corresponden a estos periodos de 30 años, según la definición
de AdapteCCa / Escenarios-PNACC:

<div class="tabla-scroll">

```{r}
desc_horizonte |>
  knitr::kable(col.names = c("horizonte", "periodo (años)", "denominación"))
```

</div>

La **línea base de referencia** del modelo es el periodo histórico **1971–2000**
(código interno `reference`). **Sí** se incluye en este rds, junto a los 3
horizontes futuros, lo que permite calcular directamente las anomalías
futuro − referencia. Al proceder del forzamiento histórico común de CMIP6, su
valor es prácticamente idéntico en los 4 escenarios SSP (se repite en cada uno
por simetría de la estructura).

Los **escenarios** son trayectorias **SSP** (*Shared Socioeconomic Pathways*) del
IPCC-AR6: cada una combina un relato socioeconómico (SSP1–5) con un nivel de
**forzamiento radiativo** en 2100 —el número del código, p. ej. `2.6` = 2,6 W/m²—
que resume el volumen de emisiones de gases de efecto invernadero (GHG). Van de
menos a más emisiones: `ssp126` (bajas) → `ssp245` (medias) → `ssp370` (altas) →
`ssp585` (muy altas). A mayor escenario, mayor calentamiento proyectado. El
detalle de cada uno está en la tabla de la sección *Escenarios de emisión (GHG / SSP)*.

Por eso los criterios AEDV de *series temporales* y *actualización* no aplican
igual (no es una serie observada): su papel es **proyectar/comparar** frente a la
línea base histórica ya validada. A continuación, un resumen de su contenido:

<div class="tabla-scroll">

```{r}
# el periodo de cada horizonte sale de los metadatos, no se vuelve a escribir aquí
periodo_horizonte <- setNames(desc_horizonte$periodo, desc_horizonte$horizonte)

resumen_proy <- tibble(
  Concepto = c("Variables", "Escenarios (SSP)", "Modelos (GCM + ensemble)",
               "Horizontes (periodo)", "Municipios", "Meses", "Filas totales"),
  Valor = c(
    as.character(n_distinct(proy$variable)),
    paste(sort(unique(as.character(proy$escenario))), collapse = ", "),
    as.character(n_distinct(proy$modelo)),
    paste(sprintf("%s (%s)", names(periodo_horizonte), periodo_horizonte),
          collapse = "; "),
    as.character(n_distinct(proy$municipio)),
    as.character(n_distinct(proy$mes)),
    format(nrow(proy), big.mark = ".", decimal.mark = ",")
  )
)

knitr::kable(resumen_proy)
```

</div>

#### Escenarios de emisión (GHG / SSP)

Detalle de las 4 trayectorias SSP presentes en el dataset de proyecciones.

**Qué significa la columna "Calentamiento 2100 (AR6)".** Es el aumento estimado de
la **temperatura media GLOBAL** del planeta a finales de siglo (media del periodo
**2081–2100**) respecto al **clima preindustrial** (referencia **1850–1900**),
según el **6º Informe de Evaluación del IPCC (AR6, Grupo de Trabajo I, 2021)**. Es
una cifra de referencia que sitúa la severidad de cada escenario; **no** es el
calentamiento concreto de Canarias —ese se obtiene de los datos regionalizados de
este mismo dataset y suele diferir del valor global.

**Cómo se obtiene.** El IPCC parte del conjunto de modelos climáticos globales
**CMIP6** y, combinándolos con el calentamiento ya observado, el paleoclima y el
conocimiento de los procesos físicos, *acota* la dispersión de los modelos para
dar, en cada escenario:

- una **mejor estimación** (el valor central), y
- un **rango "muy probable"** (entre paréntesis) que, en el lenguaje calibrado del
  IPCC, cubre del **percentil 5 al 95** (≈ 90 % de probabilidad).

Así, `ssp585` → *~4,4 °C (3,3–5,7)* se lee: la mejor estimación es **+4,4 °C** y es
muy probable que el calentamiento global en 2100 quede **entre +3,3 y +5,7 °C**.

<div class="tabla-scroll-xy con-desc">

```{r}
desc_escenario |>
  knitr::kable(col.names = c("Escenario", "SSP", "Relato", "Forzamiento 2100",
                             "Emisiones", "Calentamiento 2100 (AR6)", "Descripción"))
```

</div>

