1. Introducción

Este es mi segundo cuaderno escrito usando R Markdown. Dicho documento ilustra el proceso llevado a cabo para realizar un mapa con polígonos que representan las ciudades de Colombia. La base de datos empleada para este fin se encuentra en el shapefile del DANE.

2. Cargar las librerías requeridas

Para comenzar, se cargan las librerías:

#install.packages(c("rgeos", "sf"))
library(rgeos)
library(sf)
library(leaflet)

3. Leer una tabla que contiene la localización de las ciudades

Ahora, se lee el dataset ciudades pero esta vez, es una tabla:

cities <- read.table(file= "C:/Users/LUISA CARRION/Downloads/ciudades.txt", header=FALSE, sep=";")
class(cities)
[1] "data.frame"
head(cities)
names(cities) <- c("ID", "Ciudad", "Latitud", "Longitud", "Altitud")
cities

Ahora, sse convierte el dataframe a un objeto espacial:

## el orden de las coordenadas: (i) longitud, (ii) latitud, (iii) altitud
m <- st_as_sf(cities, coords = c(5,4,6))
m
Simple feature collection with 100 features and 3 fields
geometry type:  POINT
dimension:      XYZ
bbox:           xmin: -81.70055 ymin: 0.8302778 xmax: -70.76167 ymax: 12.58472
CRS:            NA
First 10 features:
        ID  Ciudad
1  2338 Colombi
2     2339 Colombi
3     2340 Colombi
4     2341 Colombi
5     2342 Colombi
6     2343 Colombi
7     2344 Colombi
8     2345 Colombi
9     2346 Colombi
10    2347 Colombi
        Latitud
1        Bogota
2          Cali
3      Medellin
4  Barranquilla
5     Cartagena
6        Cucuta
7   Bucaramanga
8       Pereira
9   Santa Marta
10       Ibague
                         geometry
1    POINT Z (-74.08334 4.6 2620)
2  POINT Z (-76.5225 3.437222 ...
3  POINT Z (-75.53611 6.291389...
4  POINT Z (-74.79639 10.96389...
5  POINT Z (-75.51444 10.39972...
6  POINT Z (-72.50528 7.883333...
7  POINT Z (-73.12583 7.129722...
8  POINT Z (-75.69611 4.813333...
9  POINT Z (-74.20167 11.24722 9)
10 POINT Z (-75.23222 4.438889...
class(m)
[1] "sf"         "data.frame"

Se procede a obtener una matriz de coordenadas:

coords <- st_coordinates(m)
class(coords)
[1] "matrix" "array" 
lat = coords[,2]
long = coords[,1]
alt = coords[,3]

4. Leer un shapefile de departamentos

deptos <- sf::read_sf("C:/Users/LUISA CARRION/Downloads/MGN2018_DPTO_POLITICO/MGN_DPTO_POLITICO.shp")
class(deptos)
st_crs(deptos)
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]]
head(deptos)
Simple feature collection with 6 features and 7 fields
geometry type:  MULTIPOLYGON
dimension:      XY
bbox:           xmin: -77.92834 ymin: -0.70584 xmax: -66.84722 ymax: 6.324317
geographic CRS: WGS 84
deptos$DPTO_CCDGO
 [1] "18" "19" "86" "76" "94"
 [6] "99" "85" "91" "97" "95"
[11] "17" "63" "66" "05" "27"
[16] "52" "23" "13" "20" "44"
[21] "47" "70" "88" "81" "15"
[26] "25" "54" "11" "50" "41"
[31] "68" "73" "08"
deptos$DPTO_CNMBR
 [1] "CAQUETÁ"                                                 
 [2] "CAUCA"                                                   
 [3] "PUTUMAYO"                                                
 [4] "VALLE DEL CAUCA"                                         
 [5] "GUAINÍA"                                                 
 [6] "VICHADA"                                                 
 [7] "CASANARE"                                                
 [8] "AMAZONAS"                                                
 [9] "VAUPÉS"                                                  
[10] "GUAVIARE"                                                
[11] "CALDAS"                                                  
[12] "QUINDIO"                                                 
[13] "RISARALDA"                                               
[14] "ANTIOQUIA"                                               
[15] "CHOCÓ"                                                   
[16] "NARIÑO"                                                  
[17] "CÓRDOBA"                                                 
[18] "BOLÍVAR"                                                 
[19] "CESAR"                                                   
[20] "LA GUAJIRA"                                              
[21] "MAGDALENA"                                               
[22] "SUCRE"                                                   
[23] "ARCHIPIÉLAGO DE SAN ANDRÉS, PROVIDENCIA Y SANTA CATALINA"
[24] "ARAUCA"                                                  
[25] "BOYACÁ"                                                  
[26] "CUNDINAMARCA"                                            
[27] "NORTE DE SANTANDER"                                      
[28] "BOGOTÁ, D.C."                                            
[29] "META"                                                    
[30] "HUILA"                                                   
[31] "SANTANDER"                                               
[32] "TOLIMA"                                                  
[33] "ATLÁNTICO"                                               
# Se necesita convertir el objeto deptos en un mapa de coordenadas
deptos2 <- deptos %>% st_transform(3116)
# Intentar con preserveTopology = FALSE
deptos3 <- sf::st_simplify(deptos2, preserveTopology =  TRUE, dTolerance = 1000)
object.size(deptos)
16290112 bytes
object.size(deptos3)
179568 bytes

Como leaflet trabaja con RRS WGS84, se necesita transformar el objeto simplificado en coordenadas geográficas:

deptos4 <- deptos3 %>% st_transform(4326)

5. Hacer el mapa

mapa <- leaflet(deptos4)
mapa <- addTiles(mapa)
labels <- sprintf("<strong>%s</strong><br/>%g unkown units</sup>", deptos4$DPTO_CNMBR, deptos4$Shape_Area) %>% lapply(htmltools::HTML)
mapa <- addPolygons(mapa, color="#444444", weight = 1, smoothFactor = 0.5, opacity = 1.0, fillOpacity =  0.5, fillColor = ~colorQuantile("PuRd", Shape_Area) (Shape_Area), highlightOptions = highlightOptions(color="pink", weight = 2, bringToFront = TRUE), label=labels, labelOptions = labelOptions(style=list("font-weight"= "normal", padding="3px 8px"), textsize = "5px", direction = "auto"))
mapa <- addMarkers(mapa, lng=long, lat=lat, popup=m$name)
mapa

6. Reproducibilidad

sessionInfo()
R version 4.0.4 (2021-02-15)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19041)

Matrix products: default

locale:
[1] LC_COLLATE=Spanish_Colombia.1252 
[2] LC_CTYPE=Spanish_Colombia.1252   
[3] LC_MONETARY=Spanish_Colombia.1252
[4] LC_NUMERIC=C                     
[5] LC_TIME=Spanish_Colombia.1252    

attached base packages:
[1] stats     graphics 
[3] grDevices utils    
[5] datasets  methods  
[7] base     

other attached packages:
[1] leaflet_2.0.4.1
[2] sf_0.9-7       
[3] rgeos_0.5-5    
[4] sp_1.4-5       

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.6             
 [2] RColorBrewer_1.1-2     
 [3] compiler_4.0.4         
 [4] pillar_1.5.0           
 [5] class_7.3-18           
 [6] tools_4.0.4            
 [7] digest_0.6.27          
 [8] jsonlite_1.7.2         
 [9] evaluate_0.14          
[10] lifecycle_1.0.0        
[11] tibble_3.0.6           
[12] lattice_0.20-41        
[13] pkgconfig_2.0.3        
[14] rlang_0.4.10           
[15] DBI_1.1.1              
[16] cli_2.3.1              
[17] crosstalk_1.1.1        
[18] yaml_2.2.1             
[19] xfun_0.21              
[20] e1071_1.7-4            
[21] stringr_1.4.0          
[22] knitr_1.31             
[23] leaflet.providers_1.9.0
[24] htmlwidgets_1.5.3      
[25] vctrs_0.3.6            
[26] classInt_0.4-3         
[27] grid_4.0.4             
[28] glue_1.4.2             
[29] R6_2.5.0               
[30] fansi_0.4.2            
[31] rmarkdown_2.7          
[32] farver_2.0.3           
[33] magrittr_2.0.1         
[34] scales_1.1.1           
[35] ellipsis_0.3.1         
[36] htmltools_0.5.1.1      
[37] units_0.7-0            
[38] rsconnect_0.8.16       
[39] assertthat_0.2.1       
[40] colorspace_2.0-0       
[41] KernSmooth_2.23-18     
[42] utf8_1.1.4             
[43] stringi_1.5.3          
[44] munsell_0.5.0          
[45] crayon_1.4.1           
LS0tDQp0aXRsZTogIk1pIHNlZ3VuZG8gY3VhZGVybm8gZW4gUiINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KZGZfcHJpbnQ6IHBhZ2VkDQotLS0NCg0KDQojIyMgMS4gSW50cm9kdWNjacOzbg0KDQpFc3RlIGVzIG1pIHNlZ3VuZG8gY3VhZGVybm8gZXNjcml0byB1c2FuZG8gW1IgTWFya2Rvd25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20pLiBEaWNobyBkb2N1bWVudG8gaWx1c3RyYSBlbCBwcm9jZXNvIGxsZXZhZG8gYSBjYWJvIHBhcmEgcmVhbGl6YXIgdW4gbWFwYSBjb24gcG9sw61nb25vcyBxdWUgcmVwcmVzZW50YW4gbGFzIGNpdWRhZGVzIGRlIENvbG9tYmlhLiBMYSBiYXNlIGRlIGRhdG9zIGVtcGxlYWRhIHBhcmEgZXN0ZSBmaW4gc2UgZW5jdWVudHJhIGVuIGVsIHNoYXBlZmlsZSBkZWwgW0RBTkVdKGh0dHBzOi8vZ2VvcG9ydGFsLmRhbmUuZ292LmNvL3NlcnZpY2lvcy9kZXNjYXJnYS15LW1ldGFkYXRvcy9kZXNjYXJnYS1tZ24tbWFyY28tZ2VvZXN0YWRpc3RpY28tbmFjaW9uYWwvKS4NCg0KIyMjIDIuIENhcmdhciBsYXMgbGlicmVyw61hcyByZXF1ZXJpZGFzDQoNClBhcmEgY29tZW56YXIsIHNlIGNhcmdhbiBsYXMgbGlicmVyw61hczogDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0V9DQojaW5zdGFsbC5wYWNrYWdlcyhjKCJyZ2VvcyIsICJzZiIpKQ0KbGlicmFyeShyZ2VvcykNCmxpYnJhcnkoc2YpDQpsaWJyYXJ5KGxlYWZsZXQpDQpgYGANCg0KIyMjIDMuIExlZXIgdW5hIHRhYmxhIHF1ZSBjb250aWVuZSBsYSBsb2NhbGl6YWNpw7NuIGRlIGxhcyBjaXVkYWRlcw0KDQpBaG9yYSwgc2UgbGVlIGVsIGRhdGFzZXQgKmNpdWRhZGVzKiBwZXJvIGVzdGEgdmV6LCBlcyB1bmEgdGFibGE6DQoNCmBgYHtyfQ0KY2l0aWVzIDwtIHJlYWQudGFibGUoZmlsZT0gIkM6L1VzZXJzL0xVSVNBIENBUlJJT04vRG93bmxvYWRzL2NpdWRhZGVzLnR4dCIsIGhlYWRlcj1GQUxTRSwgc2VwPSI7IikNCmBgYA0KDQoNCmBgYHtyfQ0KY2xhc3MoY2l0aWVzKQ0KYGBgDQoNCg0KYGBge3J9DQpoZWFkKGNpdGllcykNCmBgYA0KDQpgYGB7cn0NCm5hbWVzKGNpdGllcykgPC0gYygiSUQiLCAiQ2l1ZGFkIiwgIkxhdGl0dWQiLCAiTG9uZ2l0dWQiLCAiQWx0aXR1ZCIpDQpgYGANCg0KYGBge3J9DQpjaXRpZXMNCmBgYA0KQWhvcmEsIHNzZSBjb252aWVydGUgZWwgKmRhdGFmcmFtZSogYSB1biBvYmpldG8gZXNwYWNpYWw6IA0KYGBge3J9DQojIyBlbCBvcmRlbiBkZSBsYXMgY29vcmRlbmFkYXM6IChpKSBsb25naXR1ZCwgKGlpKSBsYXRpdHVkLCAoaWlpKSBhbHRpdHVkDQptIDwtIHN0X2FzX3NmKGNpdGllcywgY29vcmRzID0gYyg1LDQsNikpDQpgYGANCg0KDQpgYGB7cn0NCm0NCmBgYA0KDQpgYGB7cn0NCmNsYXNzKG0pDQpgYGANCg0KU2UgcHJvY2VkZSBhIG9idGVuZXIgdW5hIG1hdHJpeiBkZSBjb29yZGVuYWRhczogDQoNCmBgYHtyfQ0KY29vcmRzIDwtIHN0X2Nvb3JkaW5hdGVzKG0pDQpgYGANCg0KYGBge3J9DQpjbGFzcyhjb29yZHMpDQpgYGANCg0KYGBge3J9DQojIFNlIGNyZWEgdW4gdmVjdG9yIGRlIGNvb3JkZW5hZGFzDQpsYXQgPSBjb29yZHNbLDJdDQpsb25nID0gY29vcmRzWywxXQ0KYWx0ID0gY29vcmRzWywzXQ0KYGBgDQoNCiMjIyA0LiBMZWVyIHVuIHNoYXBlZmlsZSBkZSBkZXBhcnRhbWVudG9zIA0KDQpgYGB7cn0NCmRlcHRvcyA8LSBzZjo6cmVhZF9zZigiQzovVXNlcnMvTFVJU0EgQ0FSUklPTi9Eb3dubG9hZHMvTUdOMjAxOF9EUFRPX1BPTElUSUNPL01HTl9EUFRPX1BPTElUSUNPLnNocCIpDQpgYGANCg0KYGBge3J9DQpjbGFzcyhkZXB0b3MpDQpgYGANCg0KDQpgYGB7cn0NCnN0X2NycyhkZXB0b3MpDQpgYGANCg0KYGBge3J9DQpoZWFkKGRlcHRvcykNCmBgYA0KDQpgYGB7cn0NCmRlcHRvcyREUFRPX0NDREdPDQpgYGANCg0KYGBge3J9DQpkZXB0b3MkRFBUT19DTk1CUg0KYGBgDQoNCmBgYHtyfQ0KIyBTZSBuZWNlc2l0YSBjb252ZXJ0aXIgZWwgb2JqZXRvIGRlcHRvcyBlbiB1biBtYXBhIGRlIGNvb3JkZW5hZGFzDQpkZXB0b3MyIDwtIGRlcHRvcyAlPiUgc3RfdHJhbnNmb3JtKDMxMTYpDQpgYGANCg0KDQpgYGB7cn0NCiMgSW50ZW50YXIgY29uIHByZXNlcnZlVG9wb2xvZ3kgPSBGQUxTRQ0KZGVwdG9zMyA8LSBzZjo6c3Rfc2ltcGxpZnkoZGVwdG9zMiwgcHJlc2VydmVUb3BvbG9neSA9ICBUUlVFLCBkVG9sZXJhbmNlID0gMTAwMCkNCmBgYA0KDQpgYGB7cn0NCm9iamVjdC5zaXplKGRlcHRvcykNCmBgYA0KDQpgYGB7cn0NCm9iamVjdC5zaXplKGRlcHRvczMpDQpgYGANCg0KQ29tbyAqbGVhZmxldCogdHJhYmFqYSBjb24gUlJTIFdHUzg0LCBzZSBuZWNlc2l0YSB0cmFuc2Zvcm1hciBlbCBvYmpldG8gc2ltcGxpZmljYWRvIGVuIGNvb3JkZW5hZGFzIGdlb2dyw6FmaWNhczoNCg0KYGBge3J9DQpkZXB0b3M0IDwtIGRlcHRvczMgJT4lIHN0X3RyYW5zZm9ybSg0MzI2KQ0KYGBgDQoNCiMjIyA1LiBIYWNlciBlbCBtYXBhDQoNCmBgYHtyfQ0KbWFwYSA8LSBsZWFmbGV0KGRlcHRvczQpDQpgYGANCg0KYGBge3J9DQptYXBhIDwtIGFkZFRpbGVzKG1hcGEpDQpgYGANCg0KYGBge3J9DQpsYWJlbHMgPC0gc3ByaW50ZigiPHN0cm9uZz4lczwvc3Ryb25nPjxici8+JWcgdW5rb3duIHVuaXRzPC9zdXA+IiwgZGVwdG9zNCREUFRPX0NOTUJSLCBkZXB0b3M0JFNoYXBlX0FyZWEpICU+JSBsYXBwbHkoaHRtbHRvb2xzOjpIVE1MKQ0KYGBgDQoNCg0KYGBge3J9DQptYXBhIDwtIGFkZFBvbHlnb25zKG1hcGEsIGNvbG9yPSIjNDQ0NDQ0Iiwgd2VpZ2h0ID0gMSwgc21vb3RoRmFjdG9yID0gMC41LCBvcGFjaXR5ID0gMS4wLCBmaWxsT3BhY2l0eSA9ICAwLjUsIGZpbGxDb2xvciA9IH5jb2xvclF1YW50aWxlKCJQdVJkIiwgU2hhcGVfQXJlYSkgKFNoYXBlX0FyZWEpLCBoaWdobGlnaHRPcHRpb25zID0gaGlnaGxpZ2h0T3B0aW9ucyhjb2xvcj0icGluayIsIHdlaWdodCA9IDIsIGJyaW5nVG9Gcm9udCA9IFRSVUUpLCBsYWJlbD1sYWJlbHMsIGxhYmVsT3B0aW9ucyA9IGxhYmVsT3B0aW9ucyhzdHlsZT1saXN0KCJmb250LXdlaWdodCI9ICJub3JtYWwiLCBwYWRkaW5nPSIzcHggOHB4IiksIHRleHRzaXplID0gIjVweCIsIGRpcmVjdGlvbiA9ICJhdXRvIikpDQpgYGANCg0KDQpgYGB7cn0NCm1hcGEgPC0gYWRkTWFya2VycyhtYXBhLCBsbmc9bG9uZywgbGF0PWxhdCwgcG9wdXA9bSRuYW1lKQ0KYGBgDQoNCmBgYHtyfQ0KbWFwYQ0KYGBgDQoNCiMjIyA2LiBSZXByb2R1Y2liaWxpZGFkIA0KDQpgYGB7cn0NCnNlc3Npb25JbmZvKCkNCmBgYA0K