# Nombre de la especie
<- "Bradypus variegatus"
especie
# Desplazamiento (offset) para delimitar el área de estudio
= 5
desplazamiento
# Resolución espacial de los datos climáticos
= 10
resolucion
# SSP
<- "585"
ssp
# GCM
<- "HadGEM3-GC31-LL"
gcm
# Proporción de datos de entreamiento a utilizar en el modelo
= 0.7 proporcion_entrenamiento
13 Modelos de nichos ecológicos - proyección a escenarios de clima futuro
13.1 Introducción
13.1.1 Trayectorias socioeconómicas compartidas (SSP)
El Panel Intergubernamental sobre Cambio Climático (IPCC, por sus siglas en inglés) proporciona proyecciones de cambio climático basadas en diferentes escenarios de emisiones de gases de efecto invernadero (GEI). Estos escenarios se denominan Trayectorias Socioeconómicas Compartidas (SSP, por sus siglas en inglés). Cada SSP está asociada con un nivel de forzamiento radiativo expresado en vatios por metro cuadrado (W/m²) para el año 2100.
Algunos ejemplos de SSP son:
- SSP1-2.6: Escenario sostenible (bajas emisiones, economía verde).
- SSP2-4.5: Escenario intermedio (desarrollo moderado con algunas reducciones de emisiones).
- SSP3-7.0: Escenario de desarrollo desigual (altas emisiones).
- SSP5-8.5: Escenario de altas emisiones (crecimiento económico dependiente de combustibles fósiles).
13.1.2 Modelos generales de circulación (GCM)
Un Modelo General de Circulación (GCM, por sus siglas en inglés) es una herramienta computacional que simula el sistema climático de la Tierra a nivel global. Representa matemáticamente los procesos físicos que gobiernan la atmósfera, los océanos, la criósfera y la biosfera. Utiliza ecuaciones basadas en la dinámica de fluidos y la termodinámica para modelar el transporte de energía, humedad y masa a través del planeta.
Algunos ejemplos de GCM son:
- ACCESS-CM2 (de CSIRO).
- GISS-E2-1-G (de la NASA).
- MPI-ESM1-2-HR (del Instituto Max Planck).
Estos modelos son desarrollados por distintas instituciones alrededor del mundo para simular el clima pasado, presente y futuro. Varían en complejidad y resolución. Se ejecutan con diferentes SSP para explorar cómo el sistema climático responderá a los cambios en las emisiones y otros factores socioeconómicos.
En este documento, se genera el modelo de nicho ecológico de una especie y se proyecta a un escenario de clima futuro.
13.2 Parámetros generales
13.3 Carga de paquetes
# Colección de paquetes de Tidyverse
library(tidyverse)
# Estilos para ggplot2
library(ggthemes)
# Paletas de colores de RColorBrewer
library(RColorBrewer)
# Paletas de colores de viridis
library(viridisLite)
# Gráficos interactivos
library(plotly)
# Manejo de datos vectoriales
library(sf)
# Manejo de datos raster
library(terra)
# Manejo de datos raster
library(raster)
# Mapas interactivos
library(leaflet)
# Acceso a datos en GBIF
library(rgbif)
# Acceso a datos climáticos
library(geodata)
# Modelado de distribución de especies
library(dismo)
13.4 Obtención de datos de presencia
# Consultar el API de GBIF
<- occ_search(
respuesta scientificName = especie,
hasCoordinate = TRUE,
hasGeospatialIssue = FALSE,
limit = 10000
)
# Extraer datos de presencia
<- respuesta$data presencia
Se puede guardar el dataframe con los datos de presencia en un archivo CSV, para no tener que repetir la consulta al API de GBIF.
# Guardar los datos de presencia en un archivo CSV
write_csv(presencia, 'presencia.csv')
El siguiente bloque debe ejecutarse si se desea leer los datos desde el archivo CSV.
# Leer en un dataframe los datos de presencia de un archivo CSV
<- read_csv('presencia.csv')
presencia
# Crear un objeto sf a partir del dataframe
<- st_as_sf(
presencia
presencia,coords = c("decimalLongitude", "decimalLatitude"),
remove = FALSE, # conservar las columnas de las coordenadas
crs = 4326
)
13.5 Delimitación del área de estudio
# Delimitar la extensión del área de estudio
<- ext(
area_estudio min(presencia$decimalLongitude) - desplazamiento,
max(presencia$decimalLongitude) + desplazamiento,
min(presencia$decimalLatitude) - desplazamiento,
max(presencia$decimalLatitude) + desplazamiento
)
13.6 Obtención de datos de clima actual
# Obtener datos climáticos actuales
<- worldclim_global(
clima_actual var = 'bio',
res = resolucion,
path = tempdir()
)
# Recortar los datos climáticos para el área de estudio
<- crop(clima_actual, area_estudio)
clima_actual
# Desplegar nombres de las variables climáticas
names(clima_actual)
[1] "wc2.1_10m_bio_1" "wc2.1_10m_bio_2" "wc2.1_10m_bio_3" "wc2.1_10m_bio_4"
[5] "wc2.1_10m_bio_5" "wc2.1_10m_bio_6" "wc2.1_10m_bio_7" "wc2.1_10m_bio_8"
[9] "wc2.1_10m_bio_9" "wc2.1_10m_bio_10" "wc2.1_10m_bio_11" "wc2.1_10m_bio_12"
[13] "wc2.1_10m_bio_13" "wc2.1_10m_bio_14" "wc2.1_10m_bio_15" "wc2.1_10m_bio_16"
[17] "wc2.1_10m_bio_17" "wc2.1_10m_bio_18" "wc2.1_10m_bio_19"
13.7 Obtención de datos de clima futuro
# Obtener datos climáticos para escenario futuro
<- cmip6_world(
clima_futuro var = "bioc",
res = resolucion,
ssp = ssp,
model = gcm,
time = "2041-2060",
path = tempdir()
)
# Recortar los datos climáticos para el área de estudio
<- crop(clima_futuro, area_estudio)
clima_futuro
# Desplegar nombres de las variables
names(clima_futuro)
[1] "bio01" "bio02" "bio03" "bio04" "bio05" "bio06" "bio07" "bio08" "bio09"
[10] "bio10" "bio11" "bio12" "bio13" "bio14" "bio15" "bio16" "bio17" "bio18"
[19] "bio19"
13.8 Modelización
13.8.1 Creación de conjuntos de entrenamiento y de evaluación
Se eliminan las coordenadas duplicadas del conjunto de datos de presencia.
# Crear dataframe con columnas de longitud y latitud
<- data.frame(
coordenadas_presencia decimalLongitude = presencia$decimalLongitude,
decimalLatitude = presencia$decimalLatitude
)
# Eliminar coordenadas duplicadas
<- unique(coordenadas_presencia) coordenadas_presencia
Se dividen los datos de presencia en dos subconjuntos:
- Entrenamiento: para desarrollar el modelo.
- Evaluación: para evaluar el modelo.
# Establecer una "semilla" para garantizar que la selección aleatoria sea reproducible
set.seed(123)
# Cantidad de registros de presencia
<- nrow(coordenadas_presencia)
n_presencia
# Con sample(), se selecciona aleatoriamente una proporción (ej. 0.7)
# de los índices de los datos de presencia para el conjunto de entrenamiento
<- sample(
indices_entrenamiento 1:n_presencia,
size = round(proporcion_entrenamiento * n_presencia)
)
# Crear el subconjunto de entrenamiento utilizando los índices seleccionados
<- coordenadas_presencia[indices_entrenamiento, ]
entrenamiento
# Crear el subconjunto de evaluación con los datos restantes
<- coordenadas_presencia[-indices_entrenamiento, ] evaluacion
13.8.2 Modelo con clima actual
# Los datos de clima deben convertirse al formato que usa el paquete raster
# debido a es este el que acepta el paquete dismo
<- raster::stack(clima_actual)
clima_actual
# Generar el modelo
<- maxent(x = clima_actual, p = entrenamiento)
modelo_actual
# Aplicar el modelo entrenado al clima actual
<- predict(modelo_actual, clima_actual) prediccion_actual
13.8.3 Modelo con clima futuro
# Convertir variables climáticas futuras al formato raster stack
<- raster::stack(clima_futuro)
clima_futuro_raster
# Asegurar que las variables tengan los mismos nombres y orden
names(clima_futuro_raster) <- names(clima_actual)
# Proyectar el modelo al clima futuro
<- predict(modelo_actual, clima_futuro_raster) prediccion_futuro
13.8.4 Diferencia
Para visualizar los cambios en la distribución potencial de la especie, podemos restar el modelo futuro menos el actual.
# Calcular la diferencia
<- prediccion_futuro - prediccion_actual diferencia
Código
# Paleta de colores del modelo con clima actual
<- colorNumeric(
colores_modelo_actual palette = c("white", "black"),
values(prediccion_actual),
na.color = "transparent"
)
# Paleta de colores del modelo con clima futuro
<- colorNumeric(
colores_modelo_futuro palette = c("white", "black"),
values(prediccion_futuro),
na.color = "transparent"
)
# Crear paleta de colores para la diferencia
<- colorNumeric(
paleta_diferencia palette = c("red", "white", "blue"),
domain = c(min(values(diferencia), na.rm = TRUE), max(values(diferencia), na.rm = TRUE)),
na.color = "transparent"
)
# Mapa de la diferencia
leaflet() |>
addTiles(group = "Mapa general") |>
addProviderTiles(
$Esri.WorldImagery,
providersgroup = "Imágenes satelitales"
|>
) addProviderTiles(
$CartoDB.Positron,
providersgroup = "Mapa blanco"
|>
) addRasterImage(
prediccion_actual,colors = colores_modelo_actual,
opacity = 0.6,
group = "Modelo con clima actual",
|>
) addRasterImage(
prediccion_futuro,colors = colores_modelo_futuro,
opacity = 0.6,
group = "Modelo con clima futuro",
|>
) addRasterImage(
diferencia,colors = paleta_diferencia,
opacity = 0.6,
group = "Diferencia",
|>
) addLegend(
title = "Modelo con clima actual",
values = values(prediccion_actual),
pal = colores_modelo_actual,
position = "bottomright",
group = "Modelo con clima actual"
|>
) addLegend(
title = "Modelo con clima futuro",
values = values(prediccion_futuro),
pal = colores_modelo_futuro,
position = "bottomright",
group = "Modelo con clima futuro"
|>
) addLegend(
title = "Diferencia",
values = values(diferencia),
pal = paleta_diferencia,
position = "bottomleft",
group = "Diferencia"
|>
) addLayersControl(
# control de capas
baseGroups = c("Mapa general", "Imágenes satelitales", "Mapa blanco"),
overlayGroups = c(
"Modelo con clima actual",
"Modelo con clima futuro",
"Diferencia"
)|>
) hideGroup("Modelo con clima actual") |>
hideGroup("Modelo con clima futuro")
En el mapa, las áreas en rojo indican una disminución en la idoneidad del hábitat, mientras que las áreas en azul indican un aumento.
13.9 Recursos de interés
Phillips, S. J., Anderson, R. P., & Schapire, R. E. (2006). Maximum entropy modeling of species geographic distributions. Ecological Modelling, 190(3-4), 231-259. https://doi.org/10.1016/j.ecolmodel.2005.03.026