Comparto aquí el vídeo donde explico como analizar datos espaciales, tanto puntos como rasters, de los datos del sismo ocurridos el pasado 10 de agosto de 2026 en San José del Palmar.
En este nuevo vídeo tutorial de mi canal de YouTube (youtube.com/fabiocastrollanos) damos un paso más allá del mapa temático tradicional y respondemos una pregunta que difícilmente se puede contestar con una sola capa: ¿la infraestructura vial de un municipio guarda relación con la pobreza de los territorios que lo rodean?
Para resolverlo aplicamos un análisis de Moran bivariado entre la longitud de vías y el Índice de Pobreza Multidimensional (IPM) a nivel municipal para toda Colombia, usando R. La variable de longitud de vías la construimos en un tutorial anterior, donde cuantificamos la red vial de cada municipio; aquí la ponemos a «conversar» con la pobreza.
1. El trasfondo
Un mapa de coropletas nos dice dónde hay valores altos o bajos de una variable. El Moran univariado da un paso más y mide si esos valores se agrupan en el espacio, es decir, si municipios «parecidos» tienden a ser vecinos. Pero en el análisis territorial la pregunta interesante casi siempre involucra dos fenómenos a la vez.
Ahí entra el Moran bivariado. En lugar de comparar una variable consigo misma, compara el valor de una variable en un municipio con el promedio de otra variable en sus vecinos (lo que técnicamente llamamos rezago espacial). El resultado es una clasificación local (LISA) que ubica a cada municipio en uno de cuatro cuadrantes:
Alto – Alto: municipios con alta longitud de vías rodeados de vecinos con alta pobreza.
Bajo – Bajo: poca vía, rodeada de vecinos con baja pobreza.
Alto – Bajo: buena dotación vial en un entorno de baja pobreza.
Bajo – Alto: poca infraestructura vial inmersa en un entorno de alta pobreza.
Este último cuadrante, el «Bajo – Alto», suele ser el más relevante para la política pública: señala bolsones de pobreza con conectividad deficiente, exactamente el tipo de territorio donde una inversión en infraestructura de transporte podría tener mayor impacto social.
Un detalle importante: el mapa final solo colorea los municipios estadísticamente significativos. La significancia se estima mediante un proceso de permutaciones (aleatorización), lo que nos permite distinguir los patrones reales de los que podrían aparecer por simple azar. Todo lo que no supera esa prueba se descarta como «Sin significancia».
En resumen, el objetivo del ejercicio no es hacer un mapa bonito, sino detectar de forma reproducible dónde coinciden espacialmente la carencia vial y la pobreza, para pasar de la intuición a la evidencia.
2. La preparación
Antes de correr una sola línea, conviene tener el entorno y los insumos ordenados. Este flujo se apoya por completo en R y en un puñado de librerías del ecosistema geoespacial:
sf para leer y manipular los datos vectoriales.
terra como soporte del manejo espacial.
tidyverse para toda la limpieza y transformación de las tablas.
rgeoda, la protagonista de este análisis: es la interfaz de GeoDa en R y contiene toda la maquinaria de autocorrelación espacial y estadísticos LISA.
ggplot2 junto con ggspatial y patchwork para la composición cartográfica.
cptcity y RColorBrewer para las paletas de color.
En cuanto a los datos de entrada, necesitamos combinar dos mundos:
Capas vectoriales: la capa municipal que ya contiene el atributo de longitud de vías (derivada de datos de INVIAS), los límites departamentales del IGAC y una capa mundial de contexto obtenida con geodata.
Datos tabulares: el IPM municipal en formato CSV, tomado del Departamento Nacional de Planeación (DNP).
El puente entre ambos es el código DANE del municipio (MPIO_CCNCT). Aquí un pequeño pero clásico dolor de cabeza: algunos códigos pierden el cero inicial al leerse (típicamente Antioquia y Atlántico), así que hay que restituir ese 0 antes de unir las tablas, o el cruce fallará silenciosamente. Por último, todas las capas se llevan a un mismo sistema de referencia (EPSG:4326) para que se alineen correctamente.
3. Comandos clave
Sin entrar línea por línea, estos son los comandos que sostienen todo el análisis y vale la pena entender a nivel conceptual:
queen_weights() → Es el punto de partida. Construye la matriz de vecindad bajo el criterio de la reina (dos municipios son vecinos si comparten un borde o incluso un solo vértice). Sin una definición de «quién es vecino de quién», no existe lo espacial en la estadística espacial: esta matriz es el cimiento de todo lo demás.
local_bimoran() → El corazón del ejercicio. Recibe la matriz de vecindad y las dos variables (vías e IPM) y calcula el Moran bivariado local para cada municipio, entregando su cuadrante y su nivel de significancia. Es la función que traduce la pregunta conceptual en un resultado cuantitativo.
lisa_clusters(), lisa_labels() y lisa_colors() → El trío que traduce el resultado a algo interpretable. La primera asigna la categoría a cada municipio, la segunda recupera las etiquetas estándar (Alto–Alto, Bajo–Alto, etc.) y la tercera aporta la paleta canónica de GeoDa, para que el mapa hable el mismo lenguaje visual que la literatura del tema.
inner_join() → El enlace entre lo tabular y lo geométrico. Es la operación que pega el IPM del DNP a la geometría municipal mediante el código DANE. Un cruce mal hecho aquí arruina todo el análisis, por eso la limpieza previa de los códigos es tan importante.
annotation_scale() y annotation_north_arrow() → Los elementos que convierten un gráfico en un mapa. La barra de escala y la flecha de norte no son adornos: son lo que le permite a cualquier lector interpretar correctamente la información. Es un paso que siempre insisto en no saltarse.
Conclusión
El Moran bivariado es una de esas técnicas que cambian la forma de leer un territorio: pasamos de describir variables por separado a detectar cómo se relacionan en el espacio. Aplicado a las vías y al IPM, nos entrega un mapa que no solo se ve bien, sino que señala con evidencia estadística dónde la falta de conectividad y la pobreza se dan la mano en Colombia.
Si quieres ver el paso a paso completo, con el código en pantalla y las decisiones metodológicas explicadas, te invito al vídeo en mi canal: youtube.com/fabiocastrollanos. Y si necesitas asesoría personalizada en temas de SIG y análisis espacial con R, escríbeme.
🗺️ ¿Cómo medir la infraestructura vial a nivel municipal con R?
Acabo de subir un nuevo video donde pasamos directo a la práctica para resolver esto. Les muestro paso a paso cómo armar el flujo de trabajo para cuantificar la infraestructura de transporte usando datos geoespaciales.
En el tutorial vemos cómo:
Filtrar la red vial (tipos 1 a 4) para quedarnos solo con lo importante.
Hacer una intersección espacial entre las vías y los municipios usando el paquete terra.
Automatizar el cálculo para sacar la longitud total (en kilómetros) por cada municipio.
Rematar con un mapa de calor para visualizar súper rápido qué zonas del país están mejor conectadas.
Si trabajan con SIG y quieren aprender a automatizar este tipo de geoprocesos en R, el tutorial te va a gustar.
En este vídeo tutorial explicamos cómo realizar un mapa bivariado entre las variables de rezago escolar y trabajo infantil a nivel municipal para Colombia, los datos son tomados del Departamento Nacional de Planeación de Colombia.
En el análisis de datos geográficos, a menudo no basta con ver una sola variable en el mapa. A veces, la pregunta real es: ¿Cómo interactúan dos fenómenos en un mismo territorio? Para responder a esto, una de las herramientas más potentes y visualmente atractivas es el Mapa Bivariado. En este post, les explicaré la lógica detrás de un script desarrollado en R para analizar la relación entre el Rezago Escolar y el Trabajo Infantil.
¿Qué es un mapa bivariado?
A diferencia de un mapa de coropletas tradicional (que usa una escala de un solo color), el mapa bivariado utiliza una matriz de colores. Esto nos permite identificar no solo dónde los valores son altos o bajos para una variable, sino dónde se combinan ambas situaciones.
La lógica del proceso
Para lograr este resultado, el flujo de trabajo se divide en tres grandes pilares:
1. Preparación de los datos espaciales
El primer paso consiste en cargar la información base (capas departamentales y bases de datos georeferenciadas). En este punto, es vital definir los límites geográficos (bbox) para que el mapa se centre exactamente en el área de interés, eliminando ruidos visuales innecesarios.
2. Clasificación bivariada (El corazón del mapa)
Aquí es donde ocurre la «magia». Utilizando la librería biscale, los datos se clasifican en grupos (generalmente terciles o cuantiles). El script toma dos variables independientes:
Eje X: Rezago Escolar.
Eje Y: Trabajo Infantil.
El resultado es una nueva columna en nuestros datos que combina ambas dimensiones en categorías únicas (por ejemplo: «Bajo-Bajo», «Alto-Bajo», «Alto-Alto»).
3. Composición y Diseño Cartográfico
Un buen mapa debe ser tan informativo como estético. La lógica del diseño incluye:
Capas de contexto: Se añade un fondo global y los límites departamentales para dar ubicación espacial.
Simbolización: Se aplica una paleta de colores específica (como DkCyan) que permite diferenciar claramente los cuadrantes de la matriz.
Elementos técnicos: Se incorporan la flecha de norte, la escala gráfica y etiquetas precisas para que cualquier lector pueda interpretar la escala.
El resultado final: La Leyenda
Lo más importante en un mapa bivariado es su leyenda en forma de diamante. El script no solo genera el mapa, sino que construye una leyenda independiente que se superpone al lienzo principal. Esta matriz nos dice, por ejemplo, que las zonas en los tonos más oscuros son aquellas donde ambos problemas sociales convergen con mayor intensidad.
Conclusión
Visualizar datos de esta manera nos permite identificar patrones críticos de forma inmediata, facilitando la toma de decisiones basada en datos geográficos. R, a través de potentes librerías como terra, sf y ggplot2, sigue siendo la herramienta líder para este tipo de análisis avanzado.
En este vídeo tutorial explico como hacer uso de la librería geoBounds dentro de R para acceder a información de shapefiles político administrativo a distintos niveles. Y podemos lograr mapas como este:
Fabio Alexander Castro Llanos: fabioalexandercastro@gmail.com wa.me/+573217850490
En este pequeño proyecto desarrollé una aplicación interactiva en R Shiny para visualizar el Palmer Drought Severity Index (PDSI) a nivel municipal en Colombia. La idea es bastante simple: poder explorar cómo cambian las condiciones de sequía o humedad mes a mes usando un mapa interactivo.
El resultado final es una app donde el usuario puede seleccionar año y mes, y automáticamente el mapa se actualiza mostrando el valor del índice en cada municipio.
La aplicación está construida usando sf, leaflet, tidyverse y Shiny, junto con algunos ajustes visuales usando bslib para darle una apariencia moderna
📦 Carga de librerías y datos
El primer paso consiste en cargar las librerías necesarias y leer los datos que vamos a usar.
En este caso se utilizan dos datasets principales:
Un shapefile simplificado de los municipios de Colombia
Además se agrega una leyenda dinámica que ayuda a interpretar los colores.
🌎 Resultado
El resultado es una pequeña aplicación interactiva que permite explorar rápidamente las condiciones de sequía o humedad en Colombia a escala municipal.
Este tipo de herramientas resulta especialmente útil para:
monitoreo climático
análisis agroclimático
exploración de datos espaciales en tiempo real
Y demuestra lo poderoso que puede ser R para construir aplicaciones geoespaciales interactivas con relativamente pocas líneas de código.
Si requieres asesoría en temas de SIG contactame a mi correo fabioalexandercastro@gmail.com o whatsapp https://wa.me/+573217850490
En este nuevo tutorial muestro cómo calcular la estadística zonal del PDSI para todos los municipios de Colombia y generar un archivo espacial final listo para análisis multitemporal.
Trabajamos con datos previamente descargados de TerraClimate, específicamente el Palmer Drought Severity Index (PDSI), y realizamos el procesamiento usando un flujo reproducible en R.
🔎 ¿Qué hace el script?
El código realiza tres procesos fundamentales:
1️⃣ Lectura y organización de rasters
Se listan todos los .tif del PDSI recortados a Colombia y se ordenan correctamente por año.
fles <- dir_ls('./tif/pdsi', regexp = '.tif$')
fles <- grep('COL', fles, value = T)
fles <- mixedsort(fles)
2️⃣ Cálculo de estadística zonal
Utilizamos exactextractr::exact_extract() para calcular el promedio mensual del PDSI por municipio:
znal <- exactextractr::exact_extract(
x = rstr,
y = st_as_sf(mpio),
fun = 'mean'
)
El resultado genera:
12 columnas (mean.PDSI_1 a mean.PDSI_12)
Una fila por municipio
Un identificador temporal por año
Todo queda organizado en una tabla estructurada.
3️⃣ Creación del archivo espacial final
Luego hacemos el join con el shapefile municipal y exportamos:
st_write(znal, './gpkg/zonal_pdsi.gpkg')
El resultado es un GeoPackage listo para:
Mapas temáticos
Dashboards en Shiny
Modelos econométricos espaciales
Análisis multitemporal por municipio
🎥 Mira el paso a paso completo
En el video del canal Un Geógrafo en YouTube explico:
Por qué usar exactextractr en lugar de terra::extract
Cómo estructurar datos multitemporales
Buenas prácticas para zonal statistics
Errores comunes y cómo evitarlos
👉 Te invito a ver el tutorial completo en el canal.
Si requieres asesoría en temas de SIG contactame a mi correo fabioalexandercastro@gmail.com o whatsapp https://wa.me/+573217850490
En este tutorial te explico cómo descargar y procesar datos climáticos del dataset TerraClimate directamente desde R, automatizando la descarga de múltiples años, recortando por país y exportando los resultados en formato GeoTIFF listo para análisis espacial.
El flujo que implementamos es completamente reproducible y escalable, ideal para proyectos de modelación climática, análisis de sequías o estudios de cambio climático.
🌎 ¿Qué es TerraClimate?
TerraClimate es un conjunto de datos climáticos mensuales de alta resolución (~4 km) que combina información de estaciones, reanálisis y climatologías históricas. Es ampliamente utilizado para estudios de:
Balance hídrico
Índices de sequía (como PDSI)
Temperatura y precipitación
Modelación ecológica
Agricultura y seguridad alimentaria
En este ejemplo trabajamos con el Palmer Drought Severity Index (PDSI).
🧠 Objetivo del flujo en R
El script realiza cuatro procesos clave:
Genera automáticamente las URLs para múltiples años.
Descarga archivos NetCDF (.nc) desde el servidor THREDDS.
Recorta y enmascara los datos usando el límite oficial de Colombia.
Exporta cada resultado como archivo GeoTIFF.
Todo esto se ejecuta con una función aplicada iterativamente.
📦 Librerías utilizadas
Trabajamos con un stack moderno y eficiente
require(pacman)
p_load(terra, fs, sf, tidyverse, gtools, glue)
🔗 Construcción automática de URLs
Generamos las rutas directamente hacia el servidor:
✔ Automatización completa ✔ Flujo reproducible ✔ Uso de terra (más eficiente que raster) ✔ Escalable a cualquier variable de TerraClimate ✔ Compatible con flujos avanzados (SPEI, modelación de especies, análisis agrícola)
🎥 Mira el video completo
En el video del canal Un Geógrafo en YouTube explico cada paso con detalle