1. Introducción y Preparación de Datos

En este documento presento un análisis espacial enfocado en la evaluación de fenómenos públicos mediante herramientas de ciencia de datos. El objetivo es visualizar la distribución territorial de la vulnerabilidad social y la accesibilidad a la infraestructura del Estado.

1.1 Justificación Cartográfica: ¿Por qué cambiamos de mapa base?

A lo largo de este reporte notarás que alternamos entre dos tipos de mapas de fondo, una decisión de diseño pensada para comunicar mejor los hallazgos:

  • CartoDB Positron: Lo utilizamos para los mapas temáticos sobre marginación y clínicas. Al ser un mapa minimalista y en escala de grises, elimina el “ruido visual” como los nombres de calles y permite que los datos y los colores sean lo más relevante.

  • OpenStreetMap (OSM): Lo utilizamos para los mapas de movilidad y ruteo. Al ser un mapa altamente detallado, permite al lector validar visualmente que las rutas peatonales y las isocronas están siguiendo fielmente la red real de calles y banquetas.

Para comenzar, preparamos nuestra base de datos. Tomamos el Marco Geoestadístico Municipal de Guanajuato y le unimos, mediante un Spatial Join, el Índice de Marginación de CONAPO.

# Carga de librerías esenciales
library(leaflet)
library(tidyverse)
library(sf)
library(readxl)
library(osrm)
library(bivariateLeaflet)
library(sfdep)
library(ellmer)

# Cargar geometrías de Guanajuato (Clave 11)
mun <- st_read("00mun.shp", quiet = TRUE)
est_interes <- mun %>% filter(CVE_ENT == 11)

# Cargar datos sociodemográficos
conapo <- read_excel("IMM_2020.xlsx", sheet = "IMM_2020")

# Unir datos y reproyectar a WGS84 para compatibilidad web
final <- est_interes %>% 
  left_join(y = conapo, by = c("CVEGEO" = "CVE_MUN")) %>% 
  st_transform(4326)



2. Mapa Bivariado de Marginación en Guanajuato

En el diseño de políticas públicas, los problemas rara vez se presentan de forma aislada. Para focalizar recursos, utilizo una técnica cartográfica bivariada que permite observar la intersección de dos variables simultáneamente.

En este mapa interactivo cruzamos el porcentaje de Analfabetismo con el porcentaje de Viviendas sin Agua Entubada. Utilizamos el lienzo limpio de CartoDB para que los tonos oscuros resalten claramente los municipios donde ambas carencias se superponen.

create_bivariate_map(
  data = final,
  var_1 = "ANALF",
  var_2 = "OVSAE"
)



3. Infraestructura de Salud en Guanajuato

Cargamos el padrón de establecimientos de salud (CLUES), extraemos sus coordenadas y mapeamos los puntos. Superponemos estas clínicas sobre una coropleta que muestra la densidad de población total. Los clústeres interactivos nos permiten evaluar si la concentración de clínicas responde de manera proporcional a las zonas más habitadas.

# Procesamiento de las clínicas a objeto espacial
clues <- read_excel("ESTABLECIMIENTO_SALUD_202602.xlsx") %>% 
  select(LONGITUD, LATITUD) %>% 
  mutate(LONGITUD = as.numeric(LONGITUD), LATITUD = as.numeric(LATITUD)) %>% 
  na.omit() %>% 
  st_as_sf(coords = c("LONGITUD", "LATITUD"), crs = 4326)

# Asignación de cada clínica a su municipio correspondiente
final_2 <- st_join(clues, final, left = TRUE) %>% filter(!is.na(CVEGEO))
colorea <- colorNumeric(palette = "viridis", domain = final$POB_TOT)

# Visualización interactiva sobre CartoDB
leaflet() %>% 
  addProviderTiles(providers$CartoDB.Positron) %>% 
  addPolygons(data = final, fillColor = ~colorea(POB_TOT), color = "white", fillOpacity = 0.6, weight = 1) %>% 
  addCircleMarkers(data = final_2, clusterOptions = markerClusterOptions())



4. Isodistancias

El análisis espacial tradicional mide distancias en línea recta. Para evaluar la accesibilidad real de los ciudadanos, calculamos el traslado peatonal utilizando la API de OSRM. A partir de aquí, cambiamos nuestro mapa base a OpenStreetMap para poder observar la red vial.

Primero, escalamos el análisis iterando el cálculo de rutas para todos los municipios del estado. Mapeamos para visualizar cómo los ciudadanos se desplazan desde sus centros municipales hasta la clínica más cercana.

# Identificar orígenes y destinos
origen <- final %>% select(NOM_MUN, GM_2020) %>% st_centroid()
destino <- final_2 %>% mutate(id = 1:n()) %>% select(id)
para_mapa <- origen %>% st_join(y = destino, join = st_nearest_feature)

# Calcular iterativamente la ruta para cada municipio
contenedor <- data.frame()
for (i in para_mapa$NOM_MUN) {
  or <- para_mapa %>% filter(NOM_MUN == i)
  de <- destino %>% filter(id == or$id)
  
  ruta <- osrmRoute(src = or, dst = de, osrm.profile = "foot")
  contenedor <- rbind(contenedor, ruta)
}

# Ploteo de la telaraña de rutas sobre OpenStreetMap
leaflet() %>% 
  addProviderTiles(providers$OpenStreetMap) %>% 
  addCircles(data = final_2, color = "red", label = "Clínica") %>% 
  addCircles(data = para_mapa, color = "blue", label = "Centro Municipal") %>% 
  addPolylines(data = contenedor, color = "black", weight = 2)


4.1 Alcance Peatonal Físico en Plaza Carso

Para medir la penetración territorial a microescala, usamos Isodistancias. A diferencia del ruteo que une un punto A con un punto B, las isodistancias nos muestran la “mancha” total del territorio que podemos cubrir caminando a diferentes rangos de distancia desde un punto de partida, respetando paredes y calles.

En este ejemplo fijamos las coordenadas de Plaza Carso (CDMX) y calculamos el alcance físico de 100, 500 y 1,000 metros caminando.

# Fijar coordenadas exactas de Plaza Carso
plaza_carso <- data.frame(lon = -99.2046, lat = 19.4420) %>% 
  st_as_sf(coords = c("lon", "lat"), crs = 4326)

# Calcular isodistancias
iso_dist <- plaza_carso %>% 
  osrmIsodistance(breaks = c(100, 500, 1000))

# Ploteo del resultado con herramienta de medición manual
leaflet() %>% 
  addProviderTiles(providers$OpenStreetMap) %>% 
  addPolygons(data = iso_dist, weight = 1, opacity = 0.5) %>% 
  addCircles(data = plaza_carso, color = "red", weight = 10) %>% 
  addMeasure(primaryLengthUnit = "meters")



5. IA y Modelos de Lenguaje para Extracción Geoespacial

Gran parte de los datos gubernamentales son no estructurados como reportes, PDFs o minutas. En esta sección demostramos la integración de Modelos de Lenguaje Grandes o LLMs directamente en R para transformar texto datos georreferenciadas.

A diferencia del código exploratorio original en donde usábamos la IA para extraer cadenas de texto, como el nombre de una persona y su lugar de origen, aquí ajustamos el enfoque por practicidad. Para hacer este reporte mucho más visual y demostrar el alcance nacional de la herramienta, le pasamos un texto a la API de Gemini y le pedimos explícitamente que identificara y extrajera las coordenadas exactas de cinco parques emblemáticos de México: el Parque Fundidora en Monterrey, el Parque Bicentenario, el Parque La Mexicana, el Parque Hundido de la Ciudad de México y el Parque Tangamanga de San Luis Potosí.

Definimos una estructura mediante type_object para obligar al modelo a regresar la información en un formato tabular directo al mapa, evitando que nos responda con texto libre o alucinaciones cartográficas.

(Nota: El código de conexión a la API se muestra a continuación. El mapa interactivo utiliza el resultado de la extracción ya procesada para mapear estos cinco parques).

# Subir un PDF al espacio de Google
archivo = google_upload("práctica_1.pdf")

# Ordenar a Gemini que actúe como un extractor de datos de los parques mencionados
p1_extractor = chat_google_gemini(
  system_prompt = "identifica los nombres de los parques mencionados en el texto y extrae las coordenadas exactas (latitud y longitud) de cada uno."
)

# Definir estrictamente la estructura (JSON) para evitar alucinaciones
type_datos = type_object(
  nombre = type_string("nombre del parque", required = FALSE),
  lat = type_number("latitud exacta del parque"),
  lng = type_number("longitud exacta del parque")
)

# Ejecutar la extracción estructurada
tipo_final = type_array(type_datos)
resultado = p1_extractor$chat_structured(archivo, type = tipo_final, "Extraer la información")



6. Geoestadística: Autocorrelación Espacial en Puebla

En el análisis espacial existe un principio fundamental conocido como la Primera Ley de la Geografía de Tobler, la cual dicta que: “Todo está relacionado con todo lo demás, pero las cosas cercanas están más relacionadas que las distantes”.

En términos de política pública, esto significa que los fenómenos sociales tienden a contagiarse en el territorio. La marginación o el analfabetismo de un municipio no es un evento aislado o aleatorio; casi siempre está fuertemente condicionado por la situación de sus vecinos.

Para medir matemáticamente este efecto de contagio, aplicamos el Índice Local de Moran (LISA) sobre la tasa de analfabetismo en el estado de Puebla.

Este modelo estadístico clasifica el territorio encontrando clústeres significativos:

  • Rojo (High-High): Focos rojos urgentes. Municipios con alto analfabetismo rodeados de vecinos en la misma situación.
  • Verde (Low-Low): Zonas prósperas. Bajo analfabetismo rodeado de vecinos iguales.
# Preparar datos del estado de Puebla (Clave 21)
est_interes_puebla <- mun %>% filter(CVE_ENT == 21)
final_puebla <- est_interes_puebla %>% left_join(y = conapo, by = c("CVEGEO" = "CVE_MUN"))
moran_p1 <- final_puebla %>% select(NOMGEO, ANALF, SBASC)

# Calcular matriz de contigüidad y pesos espaciales
m2 <- moran_p1 %>% 
  mutate(id = 1:n()) %>% 
  mutate(nb = st_contiguity(geometry),
         wt = st_weights(nb))

# Calcular y graficar el Índice de Moran Local con la paleta divergente
m2 %>%
  mutate(moran = local_moran(ANALF, nb, wt)) %>% 
  tidyr::unnest(moran) %>% 
  mutate(pysal = ifelse(p_folded_sim <= 0.1, as.character(pysal), NA)) %>% 
  ggplot(aes(fill = pysal)) +
  geom_sf(lwd = 0.2, color = "white") +
  theme_void() +
  scale_fill_manual(values = c("#B20016", "#E27C7C", "#94C9A9", "#24975E"), 
                    na.value = "grey90", 
                    name = "Clústeres LISA") +
  labs(title = "Autocorrelación Espacial del Analfabetismo",
       subtitle = "Índice Local de Moran en el Estado de Puebla",
       caption = "Nota: Las áreas en gris no presentan autocorrelación espacial significativa.")



7. Conclusiones

A lo largo de este documento, hemos transitado desde la visualización descriptiva de la marginación hasta el modelado geoestadístico avanzado y la integración de Inteligencia Artificial. La ciencia de datos espaciales aplicada al sector público no consiste únicamente en generar mapas atractivos, sino en construir evidencia empírica robusta para la toma de decisiones. Al comprender cómo se superponen las carencias sociales, medir la accesibilidad real y asimétrica a la infraestructura del Estado, e identificar estadísticamente los patrones de contagio territorial, logramos transformar datos en “crudo” en inteligencia pública accionable. La adopción de estas metodologías computacionales representa un paso fundamental hacia el diseño de intervenciones y políticas públicas más precisas, eficientes y territorialmente justas.