El paquete sf de R se diseñó para facilitar el trabajo con el estándar «Simple Features» (sf) para la representación de datos vectoriales geográficos dentro del ecosistema de R. El paquete sf se lanzó por primera vez en 2016 y, en pocos años, había superado con creces al paquete sp (lanzado por primera vez en 2005) como la representación de datos geográficos más utilizada para datos vectoriales en R. Además de ofrecer compatibilidad con el estándar de datos «simple features», sf incluye una amplia gama de funciones para trabajar con datos vectoriales espaciales en R. Si estás acostumbrado a trabajar con datos espaciales utilizando software tradicional de SIG de escritorio, como QGIS o ArCGIS, encontrarás en el paquete sf, potenciado por los paquetes de tidyverse, equivalentes a las herramientas típicas de SIG para el análisis, la consulta, la selección, el geoprocesamiento y la visualización.
«Simple Features» (sf) o «Simple Feature Access» hace referencia a un estándar formal (ISO 19125-1:2004) que describe cómo se pueden representar en los ordenadores los objetos del mundo real, haciendo hincapié en la geometría espacial de dichos objetos. También describe cómo se pueden almacenar y recuperar dichos objetos de las bases de datos, y qué operaciones geométricas deben definirse para ellos. La norma está ampliamente implementada en bases de datos espaciales (como PostGIS), SIG comerciales (p. ej., ESRI ArcGIS) y constituye la base de datos vectoriales para bibliotecas como GDAL.
Este cuaderno te servirá de introducción al paquete sf y al trabajo con datos vectoriales geográficos según el estándar de datos «Simple Features» (sf). Este cuaderno solo pretende ser una introducción muy breve al paquete sf, ya que aquí no se tratarán muchas otras funciones de sf.
Disponer de una copia del archivo shapefile MGN2023_MPIO_POLITICO, disponible en DANE (y utilizado desde el inicio del curso de Geomática Básica).
Una exploración de Simple Features para R
Uso de sf para datos espaciales e introducción a la creación de mapas
Configuración
Lectura y escritura de datos espaciales
Creación y visualización de objetos espaciales
Este cuaderno debe estar ubicado en tu directorio GB2, cerca del directorio donde hayas guardado tus datos.
Este cuaderno requiere los siguientes paquetes y funciones de R.
sf · Compatibilidad con «simple features», una forma estandarizada de codificar datos vectoriales espaciales. - Se integra con GDAL para leer y escribir datos, con GEOS para operaciones geométricas y con PROJ para conversiones de proyección y transformaciones de sistemas de referencia. - Utiliza por defecto el paquete s2 para operaciones de geometría esférica en coordenadas elipsoidales (longitud/latitud). · Este cuaderno utiliza las siguientes funciones de sf:
st_as_sf · convierte un objeto externo en un objeto sf
st_bbox · devuelve el cuadro delimitador de una entidad simple o un conjunto de entidades simples
st_geometry · obtiene, establece, sustituye o renombra la geometría de un objeto sf
st_read · lee entidades simples o capas desde un archivo o una base de datos
st_write · escribe un objeto de entidades simples en un archivo o una base de datos
dplyr - dplyr es una gramática de manipulación de datos que proporciona un conjunto coherente de verbos que te ayudan a resolver los retos más comunes en la manipulación de datos:
mutate() añade nuevas variables que son funciones de variables existentes
select() selecciona variables en función de sus nombres.
filter() selecciona casos en función de sus valores.
summarise() reduce varios valores a un único resumen.
arrange() cambia el orden de las filas.
ggplot2: ggplot2 es un sistema para crear gráficos de forma declarativa, basado en «The Grammar of Graphics». Tú proporcionas los datos, le indicas a ggplot2 cómo asignar las variables a los parámetros estéticos y qué primitivas gráficas utilizar, y él se encarga de los detalles.
ggspatial: los datos espaciales, combinados con la potencia del marco de trabajo de ggplot2, facilitan la creación de mapas.
Puedes instalar las bibliotecas necesarias desde la consola utilizando install.packages(«nombre_de_la_biblioteca»). Si la instalación se realiza correctamente, deberás cargar sf y dplyr para utilizar sus funciones:
library(sf)
## Linking to GEOS 3.14.1, GDAL 3.12.1, PROJ 9.7.1; sf_use_s2() is TRUE
library(dplyr)
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2) # Graficación avanzada
library(ggspatial) # Escala gráfica y flecha de norte
La función st_read del paquete sf lee datos vectoriales espaciales desde diversos formatos compatibles con GDAL (Geospatial Data Abstraction Library), entre los que se incluyen ESRI Shapefile (.shp), GeoJSON (.geojson), GeoPackage (.gpkg), KML (.kml) y KMZ (.kmz), CSV con WKT (texto bien conocido) (.csv) y otros.
st_read simplifica el proceso de lectura de datos espaciales al reconocer automáticamente el formato del archivo y devolver los datos como un objeto de características simples (sf).
#Get the filenames close to your notebook
list.files(".//datos")
## [1] "Depto_Guajira.gpkg" "Guaj_munic.gpkg" "Guajira"
## [4] "Guajira.dbf" "Guajira.gpkg" "Guajira.prj"
## [7] "Guajira.qmd" "Guajira.shp" "Guajira.shx"
## [10] "Guajira_final.gpkg" "Guajira_nueva.gpkg" "Guajira11111.gpkg"
## [13] "Guajira2.gpkg" "Guajirann.gpkg" "imagen 1.png"
## [16] "imagen 2.png" "Mun_Guajira.gpkg" "municipios.gpkg"
## [19] "Municipios2025.gpkg" "worldcities.csv"
Ahora puedes especificar la ruta relativa para leer el archivo Shapefile:
# leer el archivo shapefile *Municipios* como un objeto sf
Guajira <- st_read(".//datos//Guajira.shp")
## Reading layer `Guajira' from data source
## `C:\Users\nicol\OneDrive - Universidad Nacional de Colombia\2026-2\geomatica\Carpeta poryectos GB\Proyecto 7\Datos\Guajira.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 15 features and 6 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -73.66494 ymin: 10.39676 xmax: -71.11296 ymax: 12.45944
## Geodetic CRS: WGS 84
Cuando utilizamos st_read para leer un archivo Shapefile, obtenemos una vista previa de algunos de los metadatos espaciales del archivo.
Los datos se han leído mediante el controlador ESRI Shapefile.
Los datos incluyen 1121 elementos (el número de municipios de Colombia) y tienen 11 campos de atributos.
El tipo de geometría es multipolígono. ¿Qué es un multipolígono?
El rectángulo delimitador es: ………… ¡Completa esta información!
El sistema de referencia de coordenadas (SRC) es MAGNA-SIRGAS. Consulta tu cuaderno de física para conocer los parámetros de este SRC.
head(Guajira)
Para exportar datos espaciales, la función st_write() permite guardar un objeto sf en diversos formatos.
Puedes especificar el formato de salida añadiendo la extensión de archivo adecuada o indicando el controlador GDAL correspondiente. Se pueden especificar opciones adicionales para controlar cómo se escriben los datos.
El parámetro append = F permite que el archivo
sobrescriba un archivo ya existente con el mismo nombre en el directorio
de trabajo.
st_write(Guajira, "Guajira2b.geojson", driver = "GeoJSON", append = F)
## Deleting layer not supported by driver `GeoJSON'
## Deleting layer `Guajira2b' failed
## Writing layer `Guajira2b' to data source `Guajira2b.geojson' using driver `GeoJSON'
## Updating existing layer Guajira2b
## Writing 15 features with 6 fields and geometry type Multi Polygon.
list.files(pattern="geojson")
## [1] "Guajira.geojson" "Guajira2b.geojson"
Guajira2 <- st_read("./Guajira.geojson")
## Reading layer `Guajira' from data source
## `C:\Users\nicol\OneDrive - Universidad Nacional de Colombia\2026-2\geomatica\Carpeta poryectos GB\Proyecto 7\Guajira.geojson'
## using driver `GeoJSON'
## Simple feature collection with 15 features and 6 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -73.66494 ymin: 10.39676 xmax: -71.11296 ymax: 12.45944
## Geodetic CRS: WGS 84
#3. Selección de elementos geográficos
La herramienta «Seleccionar por atributos» del software SIG nos permite introducir una expresión de consulta SQL para seleccionar los elementos geográficos que cumplan con los criterios de selección.
Por otro lado, sf y dplyr ofrecen opciones bastante sencillas y directas para realizar operaciones similares. Veamos una de ellas.
#(Guajira <- dplyr::filter(Guajira, NAME_1 =="La Guajira")) NO ES NECESARIO PORQUE LOS DATOS YA ESTAN FILTRADOS
Revisa el número de características seleccionadas. ¿Coincide con la información que tenías anteriormente sobre tu departamento?
Entonces, hagamos un mapa muy básico de los municipios de Santander:
plot(st_geometry(Guajira), col = sf.colors(12, categorical = TRUE), border = 'grey',
axes = TRUE)
plot(st_geometry(st_centroid(Guajira)), pch = 3, col = 'red', add = TRUE)
## Warning: st_centroid assumes attributes are constant over geometries
Tenga en cuenta que trazamos los límites de los municipios, así como sus
centroides.
Ahora, podemos guardar los elementos seleccionados en un nuevo archivo Geopackage para usarlos más adelante:
##st_write( Guajira,"./datos/Guajirann.gpkg",layer = "Guajira",driver = "GPKG", append = FALSE)
Una operación muy común al trabajar con datos geográficos es el proceso de seleccionar elementos en función de una relación espacial con otro objeto (capa). En el software SIG, este proceso suele realizarse mediante la herramienta «Seleccionar por ubicación». Esta herramienta permite seleccionar elementos basándose en las siguientes relaciones:
intersección: Se seleccionarán los elementos de la capa de entrada si se cruzan con un elemento de selección. Esta es la opción predeterminada.
dentro_de_una_distancia: Se seleccionarán los elementos de la capa de entrada si se encuentran dentro de la distancia especificada (utilizando la distancia euclidiana) de un elemento de selección. Usa el parámetro distancia_de_búsqueda para especificar la distancia.
contiene: Se seleccionarán los elementos de la capa de entrada si contienen un elemento de selección.
contiene_completamente: Se seleccionarán los elementos de la capa de entrada si contienen completamente un elemento de selección.
within: Se seleccionarán los elementos de la capa de entrada si se encuentran dentro de un elemento de selección.
completely_within: Se seleccionarán los elementos de la capa de entrada si se encuentran completamente dentro de un elemento de selección o están contenidos por él.
are_identical_to: Se seleccionarán los elementos de la capa de entrada si son idénticos (en geometría) a un elemento de selección.
toca_el_límite: Se seleccionarán los elementos de la capa de entrada si tienen un límite que toca un elemento de selección. Cuando los elementos de entrada son líneas o polígonos, el límite del elemento de entrada solo puede tocar el límite del elemento de selección, y ninguna parte del elemento de entrada puede cruzar el límite del elemento de selección.
comparten_un_segmento_de_línea_con: Se seleccionarán los elementos de la capa de entrada si comparten un segmento de línea con un elemento de selección. Tanto los elementos de entrada como los de selección deben ser líneas o polígonos.
cruzados_por_el_contorno_de: Se seleccionarán los elementos de la capa de entrada si son cruzados por el contorno de un elemento de selección. Tanto los elementos de entrada como los de selección deben ser líneas o polígonos. Si se utilizan polígonos para la capa de entrada o de selección, se utilizará el contorno (línea) del polígono. Se seleccionarán las líneas que se crucen en un punto; no se seleccionarán las líneas que compartan un segmento de línea.
have_their_center_in: Se seleccionarán los elementos de la capa de entrada si su centro se encuentra dentro de un elemento de selección. El centro de la entidad se calcula de la siguiente manera: para polígonos y multipuntos, se utiliza el centroide de la geometría; para entradas de línea, se utiliza el punto medio de la geometría.
Ilustremos la funcionalidad de selección por ubicación.
Primero, leamos un archivo CSV con ciudades del mundo. Sí, este es el mismo archivo que usamos hace varias semanas en este curso. ¿Recuerdas el SCR de este archivo?
cities = read.csv('.//datos//worldcities.csv') %>%
st_as_sf(coords=c("lng","lat"), crs=4326) # remember x=longitude and y=latitude
¿Qué son las ciudades?
cities
Quizás hayamos notado que el CRS de los dos conjuntos de datos (es decir, «santander» y «cities») no coinciden. Demostremos esto:
st_crs(cities)$epsg
## [1] 4326
st_crs(Guajira)$epsg
## [1] 4326
Antes de utilizar cualquier selección por ubicación, debemos transformar el SCR de las ciudades para que coincida con el SCR de Santander. Podemos hacerlo utilizando la función st_transform:
# take note of this function sintax
ncities <- st_transform(cities, crs= st_crs(Guajira))
Ahora ya estamos listos para empezar:
Guaj_cities <- ncities[Guajira, , op = st_within]
¿Obtuvimos lo que esperábamos?
Verifiquémoslo nuevamente con un gráfico sencillo:
plot(st_geometry(Guajira), col = sf.colors(12, categorical = TRUE), border = 'grey', axes = TRUE)
plot(st_geometry(Guaj_cities), pch = 20, col = 'red', add = TRUE)
Observa la variedad de símbolos que se pueden utilizar para representar geometrías puntuales:
Usaremos ggplot() y llamaremos a geom_sf(), lo cual le indica a R que estamos trabajando con datos espaciales. Al crear un mapa, también es fundamental considerar el orden de nuestras capas. Si colocamos nuestros datos de ciudades (stder_cities) antes del polígono de los municipios de Santander (santander), las ciudades quedarán debajo del polígono de los municipios y no podremos verlas.
ggplot() +
#Add municipalities
geom_sf(data = Guajira) +
#Add cities layer
geom_sf(data = Guaj_cities, aes(color = city, label = city), size = 3) +
#Add titles
labs(x = "Longitud", y = "Latitud", title = "Ciudades de Santander") +
#Add theme
theme_bw()
## Warning in layer_sf(geom = GeomSf, data = data, mapping = mapping, stat = stat,
## : Ignoring unknown aesthetics: label
## 4.2 Creación de gráficos con ggplot y ggspatial
Ahora agregaremos algunos elementos personalizados a nuestro mapa, como una flecha de norte y una barra de escala, utilizando el paquete ggspatial de R.
ggplot() +
#Recortar los límites de Virginia a la extensión espacial de las ciudades y agregar la capa de Virginia
geom_sf(data = Guajira) +
#Agregar capa de ciudades
geom_sf(data = Guaj_cities, aes(color = city, label = city), size = 3) +
#Agregar una barra de escala en la esquina inferior izquierda desde ggspatial
annotation_scale(location = "tl", height = unit(.25, "cm"),
width = unit(1, "cm"), pad_x = unit(0.3, "in"),
pad_y = unit(0.5, "in")) +
#Agregar una flecha de norte en la esquina inferior izquierda desde ggspatial
annotation_north_arrow(height = unit(1, "cm"), width = unit(1, "cm"),
which_north = "true", location = "tl",
pad_x = unit(0.5, "in"), pad_y = unit(0.05, "in")) +
#Agregar títulos
labs(x = "Longitud", y = "Latitud", title = "Ciudades de Santander") +
#Agregar tema
theme_bw()
## Warning in layer_sf(geom = GeomSf, data = data, mapping = mapping, stat = stat,
## : Ignoring unknown aesthetics: label
## Warning in annotation_scale(location = "tl", height = unit(0.25, "cm"), :
## Ignoring unknown parameters: `width`
Si obtuviste resultados similares a los que se muestran arriba,
¡¡¡felicidades!!!
sessionInfo()
## R version 4.6.2 (2026-10-29 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 11 x64 (build 26200)
##
## Matrix products: default
## LAPACK version 3.12.1
##
## locale:
## [1] LC_COLLATE=Spanish_Colombia.utf8 LC_CTYPE=Spanish_Colombia.utf8
## [3] LC_MONETARY=Spanish_Colombia.utf8 LC_NUMERIC=C
## [5] LC_TIME=Spanish_Colombia.utf8
##
## time zone: America/Bogota
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] ggspatial_1.1.11 ggplot2_4.0.3 dplyr_1.2.1 sf_1.1-3
##
## loaded via a namespace (and not attached):
## [1] gtable_0.3.6 jsonlite_2.0.0 compiler_4.6.2 tidyselect_1.2.1
## [5] Rcpp_1.1.2 jquerylib_0.1.4 scales_1.4.0 yaml_2.3.12
## [9] fastmap_1.2.0 R6_2.6.1 generics_0.1.4 classInt_0.4-11
## [13] s2_1.1.13 knitr_1.52 tibble_3.3.1 units_1.0-1
## [17] DBI_1.3.0 bslib_0.12.0 pillar_1.11.1 RColorBrewer_1.1-3
## [21] rlang_1.3.0 cachem_1.1.0 xfun_0.62 sass_0.4.10
## [25] S7_0.2.2 otel_0.2.0 cli_3.6.6 withr_3.0.3
## [29] magrittr_2.0.5 wk_0.9.5 class_7.3-24 digest_0.6.39
## [33] grid_4.6.2 rstudioapi_0.19.0 lifecycle_1.0.5 vctrs_0.7.3
## [37] KernSmooth_2.23-27 proxy_0.4-29 evaluate_1.0.5 glue_1.8.1
## [41] farver_2.1.2 e1071_1.7-17 rmarkdown_2.32 tools_4.6.2
## [45] pkgconfig_2.0.3 htmltools_0.5.9