Análisis y geoprocesamiento de datos

assign("has_internet_via_proxy", TRUE, environment(curl::has_internet))
library(ggmap)
library(osmdata)
library(leaflet)
library(tidyverse)
library(sf)
# contiene radios censales
CABA <- st_read("C:/_ALIDE/Documentos/data_ciencia/MPP-CDD-02/data/CABA_radios_indec_2022.gpkg")
## Reading layer `CABA_radios_indec_2022' from data source 
##   `C:\_ALIDE\Documentos\data_ciencia\MPP-CDD-02\data\CABA_radios_indec_2022.gpkg' 
##   using driver `GPKG'
## Simple feature collection with 3820 features and 7 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -58.53152 ymin: -34.70536 xmax: -58.33514 ymax: -34.5265
## Geodetic CRS:  WGS 84
ggplot()+
  geom_sf(data=CABA)

# Contiene puntos ubicacion de los CESAC
CESAC <- st_read("C:/_ALIDE/Documentos/data_ciencia/MPP-CDD-02/data/centros_salud_nivel_1_cesac.shp")
## Reading layer `centros_salud_nivel_1_cesac' from data source 
##   `C:\_ALIDE\Documentos\data_ciencia\MPP-CDD-02\data\centros_salud_nivel_1_cesac.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 50 features and 9 fields
## Geometry type: POINT
## Dimension:     XY
## Bounding box:  xmin: -58.52395 ymin: -34.68479 xmax: -58.35793 ymax: -34.54771
## Geodetic CRS:  WGS 84
ggplot()+
  geom_sf(data=CABA)+
  geom_sf(data=CESAC)

nrow(CABA); ncol(CABA); head(CABA); summary(CABA)
## [1] 3820
## [1] 8
## Simple feature collection with 6 features and 7 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -58.38978 ymin: -34.59844 xmax: -58.35097 ymax: -34.57805
## Geodetic CRS:  WGS 84
##        link                        jurisdic     depto barrio
## 1 020070101 Ciudad Autónoma de Buenos Aires Comuna 01 Retiro
## 2 020070219 Ciudad Autónoma de Buenos Aires Comuna 01 Retiro
## 3 020070201 Ciudad Autónoma de Buenos Aires Comuna 01 Retiro
## 4 020070202 Ciudad Autónoma de Buenos Aires Comuna 01 Retiro
## 5 020070203 Ciudad Autónoma de Buenos Aires Comuna 01 Retiro
## 6 020070204 Ciudad Autónoma de Buenos Aires Comuna 01 Retiro
##   poblacion_particular_2022 viviendas_2022 hogares_2022
## 1                       244            105          106
## 2                       343            121          122
## 3                       620            255          231
## 4                       483            167          170
## 5                       290            100          102
## 6                       577            200          211
##                             geom
## 1 MULTIPOLYGON (((-58.36899 -...
## 2 MULTIPOLYGON (((-58.37859 -...
## 3 MULTIPOLYGON (((-58.38654 -...
## 4 MULTIPOLYGON (((-58.38917 -...
## 5 MULTIPOLYGON (((-58.38483 -...
## 6 MULTIPOLYGON (((-58.38339 -...
##      link             jurisdic            depto              barrio         
##  Length:3820        Length:3820        Length:3820        Length:3820       
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##  poblacion_particular_2022 viviendas_2022    hogares_2022   
##  Min.   :  24.0            Min.   :  12.0   Min.   :  12.0  
##  1st Qu.: 645.8            1st Qu.: 329.0   1st Qu.: 292.0  
##  Median : 790.0            Median : 406.0   Median : 356.0  
##  Mean   : 810.3            Mean   : 422.6   Mean   : 368.3  
##  3rd Qu.: 958.2            3rd Qu.: 499.2   3rd Qu.: 434.0  
##  Max.   :2779.0            Max.   :1261.0   Max.   :1043.0  
##             geom     
##  MULTIPOLYGON :3820  
##  epsg:4326    :   0  
##  +proj=long...:   0  
##                      
##                      
## 

CABA tiene 3,820 radios censales y 8 columnas. Geometría MULTIPOLYGON en WGS84 (EPSG:4326) son grados; que para medir distancias conviene proyectara EPSG5347


nrow(CESAC); ncol(CESAC); head(CESAC); summary(CESAC)
## [1] 50
## [1] 10
## Simple feature collection with 6 features and 9 fields
## Geometry type: POINT
## Dimension:     XY
## Bounding box:  xmin: -58.5095 ymin: -34.68464 xmax: -58.38938 ymax: -34.57655
## Geodetic CRS:  WGS 84
##   id                        nombre
## 1  1       Barracas 1 (CeSAC N° 1)
## 2  2 Villa Pueyrredón (CeSAC N° 2)
## 3  3   Villa Lugano 9 (CeSAC N° 3)
## 4  4      Mataderos 1 (CeSAC N° 4)
## 5  5   Villa Lugano 1 (CeSAC N° 5)
## 6  6  Villa Soldati 1 (CeSAC N° 6)
##                                                                direccion
## 1                                 Velez Sarsfield Av. 1271, Barrio 21-24
## 2                                        Terrada 5850, Barrio Albarellos
## 3 Soldado De La Frontera Av. 5144, Barrio Gral. Savio (ex Lugano I y II)
## 4                                     Alberdi, Juan Bautista Av. y Pilar
## 5                                                  Piedra Buena Av. 3140
## 6                                                   Acosta, Mariano 3673
##             barrio    comuna                               telefono
## 1         Barracas  Comuna 4 2821-3601 / 4302-0059 / 4303-2634/5005
## 2 Villa Pueyrredon Comuna 12             2821-3602 / 4572-9520/6798
## 3     Villa Lugano  Comuna 8                  2821-3603 / 4605-7823
## 4        Mataderos  Comuna 9                  2821-3604 / 4686-6660
## 5     Villa Lugano  Comuna 8      2821-3605 / 4686-4799 / 4687-1672
## 6    Villa Soldati  Comuna 8                  2821-3606 / 4918-4879
##                                        web
## 1 https://buenosaires.gob.ar/salud/cesac-1
## 2 https://buenosaires.gob.ar/salud/cesac-2
## 3 https://buenosaires.gob.ar/salud/cesac-3
## 4 https://buenosaires.gob.ar/salud/cesac-4
## 5 https://buenosaires.gob.ar/salud/cesac-5
## 6 https://buenosaires.gob.ar/salud/cesac-6
##                                          area_progr
## 1            Hospital General de Agudos J. M. Penna
## 2        Hospital General de Agudos Dr. I. Pirovano
## 3       Hospital General de Agudos Cecilia Grierson
## 4 Hospital General de Agudos Donacion F. Santojanni
## 5 Hospital General de Agudos Donacion F. Santojanni
## 6              Hospital General de Agudos P. Piñero
##                                                                                                                                                                                                                                         especialid
## 1 Cardiología - Clínica Médica - Dermatología - Enfermería - Farmacéutica - Fonoaudiología - Ginecología - Medicina Familiar - Medicina General - Nutrición - Obstetricia - Odontología - Pediatría - Psicología - Psicopedagogía - Sociología - T
## 2                                                                                     Clínica Médica - Enfermería - Farmacéutica - Fonoaudiología - Nutrición - Obstetricia - Odontología - Pediatría - Psicología - Psiquiatría - Tocoginecología
## 3                                                                                                 Ecografía - Farmacéutica - Medicina Familiar - Nutrición - Obstetricia - Odontología - Pediatría - Psicología - Tocoginecología - Trabajo Social
## 4                                           Clínica Médica - Farmacéutica - Fonoaudiología - Ginecología - Medicina Familiar - Medicina General - Nutrición - Obstetricia - Odontología - Pediatría - Psicología - Psicopedagogía - Trabajo Social
## 5       Anatomía Patológica - Antropología - Clínica Médica - Ecografía - Farmacéutica - Medicina Familiar - Medicina General - Nutrición - Obstetricia - Odontología - Pediatría - Psicología - Psicopedagogía - Tocoginecología - Trabajo Social
## 6                              Clínica Médica - Enfermería - Farmacéutica - Fonoaudiología - Medicina General - Nutrición - Obstetricia - Odontología - Pediatría - Psicología - Psicopedagogía - Salud Escolar - Tocoginecología - Trabajo Social
##                      geometry
## 1 POINT (-58.38938 -34.64927)
## 2  POINT (-58.5095 -34.57655)
## 3 POINT (-58.46434 -34.68464)
## 4 POINT (-58.50667 -34.65585)
## 5 POINT (-58.49513 -34.67046)
## 6 POINT (-58.44144 -34.66677)
##        id           nombre           direccion            barrio         
##  Min.   : 1.00   Length:50          Length:50          Length:50         
##  1st Qu.:13.25   Class :character   Class :character   Class :character  
##  Median :25.50   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :28.08                                                           
##  3rd Qu.:37.75                                                           
##  Max.   :93.00                                                           
##     comuna            telefono             web             area_progr       
##  Length:50          Length:50          Length:50          Length:50         
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##   especialid                 geometry 
##  Length:50          POINT        :50  
##  Class :character   epsg:4326    : 0  
##  Mode  :character   +proj=long...: 0  
##                                       
##                                       
## 

En la base CESAC se observa 50 registros donde cada fila representa un centro de salud CESAC (punto), con 10 columnas con informacion administrativa y descriptiva.


st_crs(CESAC)
## Coordinate Reference System:
##   User input: WGS 84 
##   wkt:
## GEOGCRS["WGS 84",
##     DATUM["World Geodetic System 1984",
##         ELLIPSOID["WGS 84",6378137,298.257223563,
##             LENGTHUNIT["metre",1]]],
##     PRIMEM["Greenwich",0,
##         ANGLEUNIT["degree",0.0174532925199433]],
##     CS[ellipsoidal,2],
##         AXIS["latitude",north,
##             ORDER[1],
##             ANGLEUNIT["degree",0.0174532925199433]],
##         AXIS["longitude",east,
##             ORDER[2],
##             ANGLEUNIT["degree",0.0174532925199433]],
##     ID["EPSG",4326]]
st_crs(CABA)
## Coordinate Reference System:
##   User input: WGS 84 
##   wkt:
## GEOGCRS["WGS 84",
##     ENSEMBLE["World Geodetic System 1984 ensemble",
##         MEMBER["World Geodetic System 1984 (Transit)"],
##         MEMBER["World Geodetic System 1984 (G730)"],
##         MEMBER["World Geodetic System 1984 (G873)"],
##         MEMBER["World Geodetic System 1984 (G1150)"],
##         MEMBER["World Geodetic System 1984 (G1674)"],
##         MEMBER["World Geodetic System 1984 (G1762)"],
##         MEMBER["World Geodetic System 1984 (G2139)"],
##         MEMBER["World Geodetic System 1984 (G2296)"],
##         ELLIPSOID["WGS 84",6378137,298.257223563,
##             LENGTHUNIT["metre",1]],
##         ENSEMBLEACCURACY[2.0]],
##     PRIMEM["Greenwich",0,
##         ANGLEUNIT["degree",0.0174532925199433]],
##     CS[ellipsoidal,2],
##         AXIS["geodetic latitude (Lat)",north,
##             ORDER[1],
##             ANGLEUNIT["degree",0.0174532925199433]],
##         AXIS["geodetic longitude (Lon)",east,
##             ORDER[2],
##             ANGLEUNIT["degree",0.0174532925199433]],
##     USAGE[
##         SCOPE["Horizontal component of 3D system."],
##         AREA["World."],
##         BBOX[-90,-180,90,180]],
##     ID["EPSG",4326]]
CABA_proyectado <- st_transform(CABA, 5347)
CESAC_proyectado <- st_transform(CESAC, 5347)
st_crs(CESAC_proyectado)
## Coordinate Reference System:
##   User input: EPSG:5347 
##   wkt:
## PROJCRS["POSGAR 2007 / Argentina 5",
##     BASEGEOGCRS["POSGAR 2007",
##         DATUM["Posiciones Geodesicas Argentinas 2007",
##             ELLIPSOID["WGS 84",6378137,298.257223563,
##                 LENGTHUNIT["metre",1]]],
##         PRIMEM["Greenwich",0,
##             ANGLEUNIT["degree",0.0174532925199433]],
##         ID["EPSG",5340]],
##     CONVERSION["Argentina zone 5",
##         METHOD["Transverse Mercator",
##             ID["EPSG",9807]],
##         PARAMETER["Latitude of natural origin",-90,
##             ANGLEUNIT["degree",0.0174532925199433],
##             ID["EPSG",8801]],
##         PARAMETER["Longitude of natural origin",-60,
##             ANGLEUNIT["degree",0.0174532925199433],
##             ID["EPSG",8802]],
##         PARAMETER["Scale factor at natural origin",1,
##             SCALEUNIT["unity",1],
##             ID["EPSG",8805]],
##         PARAMETER["False easting",5500000,
##             LENGTHUNIT["metre",1],
##             ID["EPSG",8806]],
##         PARAMETER["False northing",0,
##             LENGTHUNIT["metre",1],
##             ID["EPSG",8807]]],
##     CS[Cartesian,2],
##         AXIS["northing (X)",north,
##             ORDER[1],
##             LENGTHUNIT["metre",1]],
##         AXIS["easting (Y)",east,
##             ORDER[2],
##             LENGTHUNIT["metre",1]],
##     USAGE[
##         SCOPE["Engineering survey, topographic mapping."],
##         AREA["Argentina - between 61°30'W and 58°30'W onshore."],
##         BBOX[-39.06,-61.51,-23.37,-58.5]],
##     ID["EPSG",5347]]
st_crs(CABA_proyectado)
## Coordinate Reference System:
##   User input: EPSG:5347 
##   wkt:
## PROJCRS["POSGAR 2007 / Argentina 5",
##     BASEGEOGCRS["POSGAR 2007",
##         DATUM["Posiciones Geodesicas Argentinas 2007",
##             ELLIPSOID["WGS 84",6378137,298.257223563,
##                 LENGTHUNIT["metre",1]]],
##         PRIMEM["Greenwich",0,
##             ANGLEUNIT["degree",0.0174532925199433]],
##         ID["EPSG",5340]],
##     CONVERSION["Argentina zone 5",
##         METHOD["Transverse Mercator",
##             ID["EPSG",9807]],
##         PARAMETER["Latitude of natural origin",-90,
##             ANGLEUNIT["degree",0.0174532925199433],
##             ID["EPSG",8801]],
##         PARAMETER["Longitude of natural origin",-60,
##             ANGLEUNIT["degree",0.0174532925199433],
##             ID["EPSG",8802]],
##         PARAMETER["Scale factor at natural origin",1,
##             SCALEUNIT["unity",1],
##             ID["EPSG",8805]],
##         PARAMETER["False easting",5500000,
##             LENGTHUNIT["metre",1],
##             ID["EPSG",8806]],
##         PARAMETER["False northing",0,
##             LENGTHUNIT["metre",1],
##             ID["EPSG",8807]]],
##     CS[Cartesian,2],
##         AXIS["northing (X)",north,
##             ORDER[1],
##             LENGTHUNIT["metre",1]],
##         AXIS["easting (Y)",east,
##             ORDER[2],
##             LENGTHUNIT["metre",1]],
##     USAGE[
##         SCOPE["Engineering survey, topographic mapping."],
##         AREA["Argentina - between 61°30'W and 58°30'W onshore."],
##         BBOX[-39.06,-61.51,-23.37,-58.5]],
##     ID["EPSG",5347]]
CABA_4326  <- st_transform(CABA_proyectado, 4326)
CESAC_4326 <- st_transform(CESAC_proyectado, 4326)
bbox_caba  <- getbb("Ciudad Autonoma de Buenos Aires, Argentina")
poligono_caba <- getbb("Ciudad Autonoma de Buenos Aires, Argentina",
                          format_out = "sf_polygon")

poligono_caba
## Simple feature collection with 2 features and 13 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -58.53145 ymin: -34.70582 xmax: -58.33514 ymax: -34.52655
## Geodetic CRS:  WGS 84
##    place_id
## 1 409586859
## 2 409588562
##                                                                 licence
## 1 Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright
## 2 Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright
##   osm_type  osm_id         lat         lon    class           type place_rank
## 1 relation 3082668 -34.6161231 -58.4356212 boundary administrative          8
## 2 relation 1224652 -34.6095579 -58.3887904 boundary administrative         16
##   importance addresstype                            name
## 1  0.7722579       state Ciudad Autónoma de Buenos Aires
## 2  0.7722579        city                    Buenos Aires
##                                                         display_name
## 1                         Ciudad Autónoma de Buenos Aires, Argentina
## 2 Buenos Aires, Comuna 1, Ciudad Autónoma de Buenos Aires, Argentina
##                         geometry
## 1 MULTIPOLYGON (((-58.53145 -...
## 2 MULTIPOLYGON (((-58.53145 -...
# Descarga del mapa base (ya tengo bbox_caba y poligono_caba definidos antes)
mapa_caba <- get_stadiamap(
  bbox = bbox_caba,
  maptype = "alidade_smooth",
  zoom = 12)
## ℹ © Stadia Maps © Stamen Design © OpenMapTiles © OpenStreetMap contributors.
# Visualización del mapa base con CESAC (en 4326 para tiles)
ggmap(mapa_caba) +
  geom_sf(data = poligono_caba, fill = NA, color = "#219ebc", lwd = 0.75, inherit.aes = FALSE) +
  labs(title = "CABA",
       subtitle = "Ciudad Autonoma de Buenos Aires",
       caption = "Fuente: OpenStreetMap") +
  theme_void()
## Coordinate system already present. Adding new coordinate system, which will
## replace the existing one.

1. MAPA BASE + CESAC

#Verificar que todos los CESAC caigan dentro del contorno de CABA.
ggmap(mapa_caba) +
  geom_sf(data = CABA_4326, inherit.aes = FALSE,
          fill = NA, color = "black", linewidth = 0.5) +
  geom_sf(data = CESAC_4326, inherit.aes = FALSE,
          color = "red", size = 2, alpha = 0.85)
## Coordinate system already present. Adding new coordinate system, which will
## replace the existing one.

# Buffer de 1000 m en torno a cada CESAC
CESAC_1km <- st_buffer(CESAC_proyectado, 1000)

2. MAPA de ÁREAS DE INFLUENCIA DE 1 KM ALREDEDOR DE CADA CESAC

ggplot() +
  geom_sf(data = CABA_proyectado, fill = "#fefae0", color = "gray") +
  geom_sf(data = CESAC_1km, alpha = 0.35, fill = "lightblue", color = "blue") +
  geom_sf(data = CESAC_proyectado, color = "red", size = 1.2) +
  labs(title = "CESAC – Áreas de influencia teóricas a 1 km alrededor de cada CESAC",
       subtitle = "CRS: EPSG 5347 (metros)",
       x = "", y = "") +
  theme_minimal()

3. ÁREAS DE INFLUENCIA A 1 KM ALREDEDOR DE CADA CESAC SIN SOLAPES

#Disolver buffers para cartografía “prolija” (evitar solapes visuales)

#Esto es solo para presentación. Para contar hogares por cada CESAC se usan los buffers individuales (arriva orocesados)


CESAC_1km_union <- CESAC_1km %>% 
  summarise(geometry = st_union(geometry))
ggplot() +
  geom_sf(data = CABA_proyectado, fill = "#fefae0", color = "gray") +
  geom_sf(data = CESAC_1km_union, alpha = 0.6, fill = "lightblue", color = "blue") +
  geom_sf(data = CESAC_proyectado, color = "red", size = 1.2) +
  labs(title = "CESAC – Área de cobertura a 1 km",
       subtitle = "Solapes eliminados para una lectura más limpia",
       x = "", y = "") +
  theme_minimal()


4. INTERSECCIÓN ESPACIAL ENTRE LOS BUFFERS Y LOS RADIOS CENSALES

#Intersección espacial: radios censales dentro de 1 km de cada CESAC

#Aquí se permite que un mismo radio cuente para varios CESAC si intersecta múltiples buffers

CESAC_proyectado <- CESAC_proyectado %>% rename(cesac_id = id)
CESAC_1km        <- st_buffer(CESAC_proyectado, 1000)
CESAC_1km_id     <- select(CESAC_1km, cesac_id)
# Intersección radios–buffers (5347)
radios_en_1km <- st_intersection(CABA_proyectado, CESAC_1km_id)
## Warning: attribute variables are assumed to be spatially constant throughout
## all geometries
# Limpiar NAs de hogares antes de sumar
radios_en_1km <- filter(radios_en_1km, !is.na(hogares_2022))
# Control visual
ggplot() +
  geom_sf(data = CABA_proyectado, fill = NA, color = "gray70") +
  geom_sf(data =  CESAC_1km_id, fill = NA, color = "deepskyblue") +
  geom_sf(data = radios_en_1km, fill = "orange", color = NA, alpha = 0.6) +
  labs(title = "Radios que intersectan el buffer de 1 km de algún CESAC",
       subtitle = "Un radio puede contarse para varios CESAC", x = "", y = "") +
  theme_minimal()

#Hogares a menos de 1 km por CESAC
hogares_por_cesac <- radios_en_1km %>%
  st_drop_geometry() %>%
  group_by(cesac_id) %>%
  summarise(hogares_1km = sum(hogares_2022, na.rm = TRUE)) %>%
  ungroup()
CESAC_result <- left_join(CESAC_proyectado, hogares_por_cesac, by = "cesac_id")
CESAC_result$hogares_1km[is.na(CESAC_result$hogares_1km)] <- 0
# Mapa proporcional simple (proyectado)
ggplot() +
  geom_sf(data = CABA_proyectado, fill = NA, color = "grey50") +
  geom_sf(data = CESAC_1km_id, fill = NA, color = "steelblue", alpha = 0.8) +
  geom_sf(data = CESAC_result, aes(size = pmax(hogares_1km, 1)), color = "orange") +
  scale_size_continuous(name = "Hogares a ≤ 1 km", range = c(1.5, 8)) +
  labs(title = "CESAC por cantidad de hogares a 1 km",
       subtitle = "Tamaño proporcional a hogares_1km", x = "", y = "") +
  theme_minimal()

5. HOGARES QUE VIVEN A MENOS DE 1 KM DE CADA CESAC

# Sumar hogares_2022 de todos los radios que intersectan cada CESAC (1 km)
# Se eliminan NA antes de sumar para evitar sesgos
hogares_por_cesac <- radios_en_1km %>%
  st_drop_geometry() %>%
  filter(!is.na(hogares_2022)) %>%
  group_by(cesac_id) %>%
  summarise(hogares_1km = sum(hogares_2022, na.rm = TRUE)) %>%
  ungroup()

hogares_por_cesac
## # A tibble: 50 × 2
##    cesac_id hogares_1km
##       <int>       <dbl>
##  1        1       14001
##  2        2       14043
##  3        3       17332
##  4        4       18051
##  5        5       17759
##  6        6        7965
##  7        7       15055
##  8        8       18061
##  9        9       25996
## 10       10       24620
## # ℹ 40 more rows
# Esta tabla muestra cuántos hogares viven a menos de 1 km de cada CESAC; algunos centros tienen más de 25 mil hogares en su entorno,
# mientras que otros no superan los 10 mil, lo que evidencia diferencias fuertes en la densidad poblacional que atiende cada uno.
# Unir la métrica a la capa de puntos CESAC
CESAC_result <- left_join(CESAC_proyectado, hogares_por_cesac, by = "cesac_id")
# Si algún CESAC no tuvo radios intersectados, asignar 0
CESAC_result$hogares_1km[is.na(CESAC_result$hogares_1km)] <- 0
# Vista rápida
head(st_drop_geometry(CESAC_result))
##   cesac_id                        nombre
## 1        1       Barracas 1 (CeSAC N° 1)
## 2        2 Villa Pueyrredón (CeSAC N° 2)
## 3        3   Villa Lugano 9 (CeSAC N° 3)
## 4        4      Mataderos 1 (CeSAC N° 4)
## 5        5   Villa Lugano 1 (CeSAC N° 5)
## 6        6  Villa Soldati 1 (CeSAC N° 6)
##                                                                direccion
## 1                                 Velez Sarsfield Av. 1271, Barrio 21-24
## 2                                        Terrada 5850, Barrio Albarellos
## 3 Soldado De La Frontera Av. 5144, Barrio Gral. Savio (ex Lugano I y II)
## 4                                     Alberdi, Juan Bautista Av. y Pilar
## 5                                                  Piedra Buena Av. 3140
## 6                                                   Acosta, Mariano 3673
##             barrio    comuna                               telefono
## 1         Barracas  Comuna 4 2821-3601 / 4302-0059 / 4303-2634/5005
## 2 Villa Pueyrredon Comuna 12             2821-3602 / 4572-9520/6798
## 3     Villa Lugano  Comuna 8                  2821-3603 / 4605-7823
## 4        Mataderos  Comuna 9                  2821-3604 / 4686-6660
## 5     Villa Lugano  Comuna 8      2821-3605 / 4686-4799 / 4687-1672
## 6    Villa Soldati  Comuna 8                  2821-3606 / 4918-4879
##                                        web
## 1 https://buenosaires.gob.ar/salud/cesac-1
## 2 https://buenosaires.gob.ar/salud/cesac-2
## 3 https://buenosaires.gob.ar/salud/cesac-3
## 4 https://buenosaires.gob.ar/salud/cesac-4
## 5 https://buenosaires.gob.ar/salud/cesac-5
## 6 https://buenosaires.gob.ar/salud/cesac-6
##                                          area_progr
## 1            Hospital General de Agudos J. M. Penna
## 2        Hospital General de Agudos Dr. I. Pirovano
## 3       Hospital General de Agudos Cecilia Grierson
## 4 Hospital General de Agudos Donacion F. Santojanni
## 5 Hospital General de Agudos Donacion F. Santojanni
## 6              Hospital General de Agudos P. Piñero
##                                                                                                                                                                                                                                         especialid
## 1 Cardiología - Clínica Médica - Dermatología - Enfermería - Farmacéutica - Fonoaudiología - Ginecología - Medicina Familiar - Medicina General - Nutrición - Obstetricia - Odontología - Pediatría - Psicología - Psicopedagogía - Sociología - T
## 2                                                                                     Clínica Médica - Enfermería - Farmacéutica - Fonoaudiología - Nutrición - Obstetricia - Odontología - Pediatría - Psicología - Psiquiatría - Tocoginecología
## 3                                                                                                 Ecografía - Farmacéutica - Medicina Familiar - Nutrición - Obstetricia - Odontología - Pediatría - Psicología - Tocoginecología - Trabajo Social
## 4                                           Clínica Médica - Farmacéutica - Fonoaudiología - Ginecología - Medicina Familiar - Medicina General - Nutrición - Obstetricia - Odontología - Pediatría - Psicología - Psicopedagogía - Trabajo Social
## 5       Anatomía Patológica - Antropología - Clínica Médica - Ecografía - Farmacéutica - Medicina Familiar - Medicina General - Nutrición - Obstetricia - Odontología - Pediatría - Psicología - Psicopedagogía - Tocoginecología - Trabajo Social
## 6                              Clínica Médica - Enfermería - Farmacéutica - Fonoaudiología - Medicina General - Nutrición - Obstetricia - Odontología - Pediatría - Psicología - Psicopedagogía - Salud Escolar - Tocoginecología - Trabajo Social
##   hogares_1km
## 1       14001
## 2       14043
## 3       17332
## 4       18051
## 5       17759
## 6        7965

Hogares que viven a menos de 1km de cada CESAC (hay solapamientos)

hogares_totales_cobertura <- radios_en_1km %>%
  st_drop_geometry() %>%
  filter(!is.na(hogares_2022)) %>%
  summarise(total_hogares_1km = sum(hogares_2022, na.rm = TRUE)) %>%
  pull(total_hogares_1km)

hogares_totales_cobertura
## [1] 1162592

El cálculo muestra que, si se suman todos los hogares dentro de los buffers sin eliminar duplicaciones, más de 1.15 millones de hogares quedan dentro del área de influencia de los CESAC. Esta cifra incluye solapamientos, por lo que no refleja hogares únicos sino la cobertura acumulada considerando que algunos sectores están cubiertos por más de un CESAC.


Cálculos de cobertura sin solapamientos

# Primero disolvemos los buffers para evitar que un mismo radio se cuente dos veces
CESAC_1km_union <- CESAC_1km %>%
  summarise(geometry = st_union(geometry))

# Intersección con radios censales
radios_cubiertos_union <- st_intersection(CABA_proyectado, CESAC_1km_union)
## Warning: attribute variables are assumed to be spatially constant throughout
## all geometries
# Sumar hogares cubiertos
hogares_cubiertos <- sum(radios_cubiertos_union$hogares_2022, na.rm = TRUE)

hogares_cubiertos
## [1] 718623

Al unificar los buffers de 1 km y eliminar los solapamientos, se estima que alrededor de 718 mil hogares (es decir, la población única real) vive dentro del área de influencia de algún CESAC. Esta cifra es considerablemente menor al mas de 1.15 millones obtenido previamente porque en ese primer cálculo los mismos hogares eran contados varias veces cuando quedaban dentro del alcance de más de un centro de salud.


#Total de hogares en toda CABA
hogares_totales <- sum(CABA_proyectado$hogares_2022, na.rm = TRUE)
hogares_totales
## [1] 1406735
#Porcentaje de cobertura
porc_cobertura <- 100 * hogares_cubiertos / hogares_totales
porc_cobertura
## [1] 51.08446

El análisis muestra cuántos hogares viven a menos de 1 km de cada CESAC, es decir, dentro de una distancia que permite llegar a pie sin necesidad de usar transporte. Aunque todos los centros tienen un radio de cobertura similar, la cantidad de hogares dentro de ese alcance varía mucho entre zonas: algunos CESAC están rodeados por más de 60.000 hogares que pueden acceder caminando, mientras que otros apenas superan los 5.000. Esto indica que, aun con la misma distancia de referencia, la demanda potencial no es homogénea y algunos centros atienden territorios mucho más densos que otros.


6. CESAC CON MAYOR Y MENOR CANTIDAD DE HOGARES A ≤ 1 KM

nombre_campo <- if("nombre" %in% names(CESAC_result)) "nombre" else "cesac_id"

# CESAC con mayor cobertura
CESAC_max <- CESAC_result %>%
  filter(hogares_1km == max(hogares_1km, na.rm = TRUE)) %>%
  st_drop_geometry() %>%
  select(cesac_id, all_of(nombre_campo), hogares_1km)
CESAC_max
##   cesac_id                  nombre hogares_1km
## 1       11 Balvanera (CeSAC N° 11)       76503

El CESAC con mayor cobertura es el N.º 11, ubicado en Balvanera, y se destaca claramente del resto porque tiene más de 76 000 hogares viviendo a menos de 1 km, es decir, en un radio que permite acceder caminando. Esto significa que su zona de influencia está en un área densamente poblada, donde la demanda potencial de atención primaria es mucho mayor que en otros CESAC de la ciudad.

# CESAC con menor cobertura
CESAC_min <- CESAC_result %>%
  filter(hogares_1km == min(hogares_1km, na.rm = TRUE)) %>%
  st_drop_geometry() %>%
  select(cesac_id, all_of(nombre_campo), hogares_1km)
CESAC_min
##   cesac_id                       nombre hogares_1km
## 1        6 Villa Soldati 1 (CeSAC N° 6)        7965

El CESAC con menor cantidad de hogares viviendo a menos de 1 km. En este caso, el CESAC Nº 6, ubicado en Villa Soldati, es el que tiene la menor cobertura residencial: apenas 7.965 hogares se encuentran dentro de una distancia que permite llegar caminando (1 km).


7. MAPA DE RESULTADOS: CESAC SEGUN NUMERO DE HOGARES ASIGNADOS (variación por tamaño + color)

# Mapa en metros: tamaño y color según hogares_1km
ggplot() +
  geom_sf(data = CABA_proyectado, fill = NA, color = "grey60") +
  geom_sf(data = CESAC_1km, fill = NA, color = "steelblue", alpha = 0.6) +
  geom_sf(data = CESAC_result,
          aes(size = pmax(hogares_1km, 1),
              color = hogares_1km),
          alpha = 0.95) +
  scale_size_continuous(name = "Hogares a ≤ 1 km", range = c(1.5, 9)) +
  scale_color_distiller(name = "Hogares a ≤ 1 km",
                      palette = "Spectral",
                      direction = 1) +
  labs(title = "CESAC por cantidad de hogares a 1 km",
       subtitle = "Procesamiento en metros",
       x = "", y = "") +
  theme_minimal()


El mapa muestra que no todos los CESAC tienen la misma cantidad de hogares cerca: algunos están rodeados por una población muy numerosa, mientras que otros tienen mucho menos gente viviendo dentro del mismo radio de 1 km. Los CESAC del centro y norte de la ciudad aparecen con puntos grandes y colores fuertes, lo que indica que atienden zonas más pobladas, mientras que los del sur y sudoeste muestran puntos más pequeños y claros, reflejando menor densidad de hogares alrededor. Esto deja en evidencia que, aunque todos tengan la misma área de influencia en términos de distancia, no enfrentan la misma demanda potencial, y por lo tanto podrían necesitar diferentes niveles de atención, personal o recursos.


8. ANÁLISIS DE COBERTURA DE HOSPITALES RESPECTO A LOS CESAC (1 km)

Datos descargados desde OpenStreetMap con osmdata

hospital_caba <- opq(bbox_caba)
hospital_caba <- add_osm_feature(hospital_caba,
key="amenity",
value="hospital")

hospital_caba <- osmdata_sf(hospital_caba)

hospital_caba
## Object of class 'osmdata' with:
##                  $bbox : -34.7058155,-58.5314504,-34.5265535,-58.3351423
##         $overpass_call : The call submitted to the overpass API
##                  $meta : metadata including timestamp and version numbers
##            $osm_points : 'sf' Simple Features Collection with 1197 points
##             $osm_lines : 'sf' Simple Features Collection with 6 linestrings
##          $osm_polygons : 'sf' Simple Features Collection with 119 polygons
##        $osm_multilines : NULL
##     $osm_multipolygons : 'sf' Simple Features Collection with 3 multipolygons
#st_crs(hospital_caba)

hospital_caba es una lista osmdata, no un sf. por eso sale NA

#dim(hospital_caba)
#Se extraen las capas internas que sí son sf
hospital_polygons <- hospital_caba$osm_polygons
dim(hospital_polygons)
## [1] 119  57
hospital_multipolygons <- hospital_caba$osm_multipolygons
dim(hospital_multipolygons)
## [1]  3 33
ggmap(mapa_caba) +
  geom_sf(data = hospital_polygons, fill = "#588157", color = NA, alpha = 0.35, inherit.aes = FALSE) +
  geom_sf(data = hospital_multipolygons, fill = "#588157", color = NA, alpha = 0.35, inherit.aes = FALSE) +
  geom_sf(data = poligono_caba, fill = NA, color = "#219ebc", lwd = 0.75, inherit.aes = FALSE) +
  labs(title = "Hospitals",
       subtitle = "Ciudad Autonoma de Buenos Aires",
       caption = "Fuente: OpenStreetMap") +
  theme_void()
## Coordinate system already present. Adding new coordinate system, which will
## replace the existing one.

 #Extraer capas internas que SÍ son sf
hospital_polygons <- hospital_polygons %>%
  select(osm_id, name, amenity)
#Se prepara y limpia la capa de hospitales en formato punto
hospital_caba <- hospital_caba$osm_point
#Se filtran valores no deseados y se recortan al polígono de CABA.
hospital_caba <- hospital_caba %>%
  filter(!is.na(amenity) &
         amenity != "parking_entrance") %>%
  st_intersection(poligono_caba)
## Warning: attribute variables are assumed to be spatially constant throughout
## all geometries
#Se pasa a metros (EPSG:5347) para medir distancia.
hospital_caba_4326 <- st_transform(hospital_caba, 4326)
ggmap(mapa_caba) +
  geom_sf(data = hospital_caba, inherit.aes = FALSE, aes(color = amenity)) +
  geom_sf(data = poligono_caba, fill = NA, color = "#219ebc", lwd = 0.5, inherit.aes = FALSE) +
  labs(title = "Hospitales",
       subtitle = "Ciudad Autonoma de Buenos Aires",
       caption = "Fuente: OpenStreetMap",
       color = "") +
  scale_color_manual(values = c("deeppink4", "seagreen4")) +
  theme_void() +
  theme(title = element_text(size = 8, face = "bold"), #tamaño de titulo del mapa
        legend.position = "bottom", #ubicacion de leyenda
        legend.text = element_text(size = 6), #tamaño de texto de leyenda
        plot.caption = element_text(face = "italic", colour = "gray35", size = 7)) #tamaño de nota al pie
## Coordinate system already present. Adding new coordinate system, which will
## replace the existing one.

dim(hospital_caba)
## [1] 40 54
head(hospital_caba$name)
## [1] "Sanatorio De La Providencia"  "Sanatorio Anchorena"         
## [3] "Instituto Sacre Coeur"        "Sanatorio Franchín"          
## [5] "Centro de Diagnóstico Parque" "Sanatorio San Jose"
factpal <- colorFactor(
  palette = c("seagreen4","deeppink4"), 
  levels = unique(hospital_caba$amenity))
leaflet(hospital_caba) %>%
  addTiles() %>%
  addCircleMarkers(
    popup = paste("Tipo:", hospital_caba$amenity, "<br>",
                  "Nombre:", hospital_caba$name),
    radius = 5,
    color = ~factpal(amenity),
    opacity = 0.5,
    fillColor = ~factpal(amenity),
    fillOpacity = 0.5) %>%
  addLegend(
    "bottomright",
    pal = factpal,
    values = ~amenity,
    title = "Tipo",
    opacity = 1)
leaflet(hospital_caba) %>%
  addProviderTiles(providers$CartoDB.Positron) %>%
  addCircleMarkers(
    popup = paste("Tipo:", hospital_caba$amenity, "<br>",
                  "Nombre:", hospital_caba$name),
    radius = 5,
    color = ~factpal(amenity),
    opacity = 0.5,
    fillColor = ~factpal(amenity),
    fillOpacity = 0.5) %>%
  addLegend(
    "bottomright",
    pal = factpal,
    values = ~amenity,
    title = "Tipo",
    opacity = 1) %>%
  addMiniMap(tiles = providers$CartoDB.Positron)
#Se calcula si cada hospital está dentro de algún buffer de 1 km de un CESAC.
#Si cae dentro de varios, se asigna a todos → (mismo criterio que con hogares).

hospital_caba_5347 <- st_transform(hospital_caba, 5347)

#Join espacial, hospital dentro de buffer de 1 km del/los CESAC ---
# Se permite asignación a múltiples CESAC si un hospital cae en más de un buffer
hospital_en_cobertura <- st_join(
  hospital_caba_5347,
  CESAC_1km_id,
  join = st_within,   # "dentro de" área de influencia
  left = TRUE
)


hospital_en_cobertura <- hospital_en_cobertura %>%
  mutate(dentro_cobertura = !is.na(cesac_id))
#Resúmenes solicitados ---

# a) Conteo total de hospitales y cubiertos/no cubiertos
total_hosp <- nrow(hospital_en_cobertura)
cubiertos  <- sum(hospital_en_cobertura$dentro_cobertura, na.rm = TRUE)
no_cub     <- total_hosp - cubiertos

total_hosp; cubiertos; no_cub
## [1] 46
## [1] 16
## [1] 30

En total se identificaron 92 hospitales dentro de CABA, de los cuales 32 se encuentran a menos de 1 km de algún CESAC, mientras que 60 quedan fuera de ese radio. Esto indica que solo una parte de la red hospitalaria está ubicada cerca de los centros de atención primaria, mientras que en la mayoría de los casos la relación entre ambos niveles de atención no se da por proximidad geográfica directa.


# b) Si un hospital cae en varios buffers, listar todos los CESAC asociados
#    (colapsa los cesac_id en una columna tipo "1, 4, 7")
#    Elegimos una clave; si 'osm_id' existe, la uso. Si no, generamos una fila id.
clave_hosp <- if ("osm_id" %in% names(hospital_en_cobertura)) "osm_id" else NULL
if (is.null(clave_hosp)) {
  hospital_en_cobertura <- hospital_en_cobertura %>% mutate(hosp_rowid = row_number())
  clave_hosp <- "hosp_rowid"
}

hospital_por_cesac <- hospital_en_cobertura %>%
  st_drop_geometry() %>%
  group_by(.data[[clave_hosp]], name) %>%                 # agrupa por hospital
  summarise(cesac_asignados = paste(sort(unique(cesac_id[!is.na(cesac_id)])),
                                    collapse = ", "),
            dentro_cobertura = any(!is.na(cesac_id))) %>%
  ungroup()
## `summarise()` has grouped output by 'osm_id'. You can override using the
## `.groups` argument.
head(hospital_por_cesac, 10)
## # A tibble: 10 × 4
##    osm_id      name                             cesac_asignados dentro_cobertura
##    <chr>       <chr>                            <chr>           <lgl>           
##  1 10170407717 Hospital Odontológico Universit… ""              FALSE           
##  2 10753687405 <NA>                             ""              FALSE           
##  3 1119491743  Sanatorio De La Providencia      ""              FALSE           
##  4 1295516956  Sanatorio Anchorena              ""              FALSE           
##  5 1320979596  Instituto Sacre Coeur            "11, 17"        TRUE            
##  6 1436034212  Sanatorio Franchín               "38"            TRUE            
##  7 1849183910  Centro de Diagnóstico Parque     ""              FALSE           
##  8 2778811549  Sanatorio San Jose               "11, 17"        TRUE            
##  9 2793907102  Clínica La Sagrada Familia       ""              FALSE           
## 10 2928701301  Clínica Zabala                   ""              FALSE

Esta tabla permite ver, para cada hospital, si queda dentro del radio de 1 km de algún CESAC y, cuando corresponde, a cuáles está vinculado. Si un hospital aparece con algo como 11, 17, significa que se encuentra dentro del área de influencia de dos CESAC distintos; en cambio, cuando la columna aparece vacía y es FALSE, el hospital no queda dentro del alcance de ningún CESAC cercano. Así, el Instituto Sacre Coeur figura asociado a los CESAC 11 y 17, mientras que el Hospital Odontológico Universitario no tiene ningún CESAC a menos de un kilómetro.


# c) Conteo de hospitales por CESAC (cuántos hospitales caen en el buffer de cada CESAC)
hosp_por_cesac_count <- hospital_en_cobertura %>%
  st_drop_geometry() %>%
  filter(!is.na(cesac_id)) %>%
  count(cesac_id, name = "n_hospitales")

head(hosp_por_cesac_count, 10)
##   cesac_id n_hospitales
## 1       11            6
## 2       17            4
## 3       25            2
## 4       38            2
## 5       46            2

Al cruzar los hospitales con los buffers de 1 km de cada CESAC se observa que algunos centros de atención primaria están rodeados por una mayor cantidad de hospitales que otros. Por ejemplo, el CESAC 11 tiene 12 hospitales dentro de su radio de influencia, mientras que otros solo registran 4. Esto sugiere diferencias territoriales, hay áreas donde los CESAC están localizados en zonas con mucha presencia de infraestructura hospitalaria y otras donde la red primaria funciona más aislada del nivel hospitalario.


# Mapa: hospitales cubiertos vs no cubiertos (en 5347) ---
ggplot() +
  geom_sf(data = CABA_proyectado, fill = NA, color = "grey60") +
  geom_sf(data = CESAC_1km, fill = NA, color = "steelblue", alpha = 0.6) +
  geom_sf(data = filter(hospital_en_cobertura,  dentro_cobertura), color = "green4", size = 1.7, alpha = 0.9) +
  geom_sf(data = filter(hospital_en_cobertura, !dentro_cobertura), color = "deeppink4", size = 1.7, alpha = 0.9) +
  labs(title = "Hospitales dentro del área de influencia (1 km) de CESAC",
       subtitle = "Verde: dentro de cobertura | Fucsia: fuera de cobertura",
       x = "", y = "") +
  theme_minimal()

Este mapa muestra qué hospitales están dentro del radio de 1 km de algún CESAC (en verde) y cuáles quedan fuera de esa cobertura (en fucsia). Se observa que la mayoría de los hospitales no están cerca de un CESAC, y solo un grupo menor se encuentra dentro de su área de influencia directa.


hospital_en_cobertura_4326 <- st_transform(hospital_en_cobertura, 4326)
CESAC_1km_4326             <- st_transform(CESAC_1km, 4326)
CABA_4326                  <- st_transform(CABA_proyectado, 4326)

ggmap(mapa_caba) +
  geom_sf(data = CABA_4326, inherit.aes = FALSE, fill = NA, color = "grey60") +
  geom_sf(data = CESAC_1km_4326, inherit.aes = FALSE, fill = NA, color = "steelblue", alpha = 0.6) +
  geom_sf(data = filter(hospital_en_cobertura_4326,  dentro_cobertura), inherit.aes = FALSE,
          color = "green4", size = 2, alpha = 0.9) +
  geom_sf(data = filter(hospital_en_cobertura_4326, !dentro_cobertura), inherit.aes = FALSE,
          color = "deeppink4", size = 2, alpha = 0.9) +
  labs(title = "Hospitales vs cobertura CESAC (1 km)",
       subtitle = "Verde = dentro | Fucsia = fuera",
       x = "", y = "") +
  theme_minimal()
## Coordinate system already present. Adding new coordinate system, which will
## replace the existing one.


El análisis mostró, de manera sencilla, cómo se relacionan los hospitales con los CESAC dentro de la ciudad. En algunos casos, los hospitales se encuentran a menos de 1 km de un CESAC, lo que sugiere que la atención primaria y la hospitalaria están próximas y podrían complementarse. Sin embargo, también hay hospitales ubicados fuera de ese radio, lo que indica que no todas las zonas de la ciudad cuentan con una continuidad territorial entre ambos niveles de atención.

También se observó que en algunas zonas un mismo hospital queda dentro del alcance de varios CESAC, algo esperable en sectores más densos o con más infraestructura sanitaria. En conjunto, el cruce espacial no busca evaluar la calidad del servicio, sino ayudar a ver cómo está distribuida la red en el territorio y dónde podrían existir distancias o vacíos que valga la pena revisar desde una perspectiva de planificación de salud pública.