install.packages("sf")
7 Librería sf
7.1 Simple Features
El paquete sf
(Pebesma, 2018, 2022), abreviatura de Simple Features, es una herramienta moderna y poderosa en el lenguaje de programación R diseñada específicamente para el manejo y análisis de datos geoespaciales. Este paquete proporciona un enfoque simple y coherente para trabajar con datos espaciales, permitiendo a los usuarios de R manipular, visualizar y analizar datos espaciales de manera eficiente y efectiva.
Desarrollado para reemplazar y ampliar las capacidades de paquetes más antiguos como sp
(Pebesma y Bivand, 2023) y rgdal
(Bivand et al., 2017), sf
ofrece una integración completa con el sistema de objetos de R y trabaja de manera armoniosa con paquetes populares en el ecosistema de R como dplyr
(Wickham, François, et al., 2023), tidyr
(Wickham, Vaughan, et al., 2023) y ggplot2
(Wickham, 2016). Esto facilita la realización de tareas comunes de manipulación de datos, como la selección, filtración y agregación, directamente en conjuntos de datos espaciales.
El paquete sf
soporta múltiples tipos de geometrías espaciales, incluyendo puntos, líneas, polígonos y sus variantes combinadas, lo que lo hace adecuado para una amplia gama de aplicaciones geoespaciales. La estructura de datos de sf
está alineada con el estándar Simple Features de la Open Geospatial Consortium, lo que garantiza la compatibilidad con una amplia variedad de herramientas y formatos de datos espaciales.
Las capacidades clave de sf
incluyen:
Lectura y escritura eficiente:
sf
puede leer y escribir una variedad de formatos de archivo geoespacial comunes, incluyendo Shapefile, GeoJSON, KML y muchos otros, a través de la integración con la biblioteca GDAL.Manipulación de datos espaciales: Permite realizar operaciones espaciales como el cálculo de distancias, áreas, intersecciones, uniones y otros tipos de análisis geométrico.
Visualización de datos espaciales: Integración con ggplot2 para la creación de visualizaciones de datos espaciales avanzadas y de alta calidad.
Análisis espacial: Facilita la realización de análisis espacial, incluyendo la medición de autocorrelación espacial o la creación de modelos de regresión espacial, entre otros.
7.2 Instalación del paquete sf
Del mismo modo que hacemos con otros paquetes, para poder utilizarlo hay que instalarlo y cargarlo.
library(sf)
Linking to GEOS 3.12.2, GDAL 3.9.3, PROJ 9.4.1; sf_use_s2() is TRUE
Cuando cargamos la librería, nos aparece un mensaje informativo. Hablaremos de esto más adelante pero, ¿a qué crees que hace referencia?
Recordemos una forma de comprobar qué versión del paquete tenemos instalada:
packageVersion("sf")
[1] '1.0.19'
7.3 Cómo crear un objeto sf
Los objetos sf
se forman como integración de unas piezas o subclases que heredan las características de la norma UNE ISO19125. Básicamente un objeto sf
se descompone en dos objetos: uno de tipo sfc
(simple feature column) y otro de tipo data.frame
. A su vez, un objeto sfc
se origina a partir de un objeto sfg
(simple feature geometry), pudiéndole añadir un CRS
(sistema de coordenadas de referencia). Los objetos sfg
pueden ser de tipo POINT, LINESTRING, etc. Veamos más detenidamente cada tipo de objeto, comenzando por los más básicos hasta llegar a sf
.
7.3.1 sfg
La clase sfg
almacena la geometría con la información gráfica del objeto: las coordenadas, dimensiones, tipo de geometría… Hay 17 tipos posibles, pero los 7 más utilizados son:
- POINT: un punto simple (un vector x,y).
- MULTIPOINT: múltiples puntos (una matriz cada fila un punto).
- LINESTRING: secuencia de 2 o mas puntos conectados por lineas rectas.
- MULTILINESTRING: múltiples lineas (lista de matrices).
- POLYGON: un polígono cerrado (lista de matrices).
- MULTIPOLYGON: múltiples polígonos.
- GEOMETRYCOLLECTION: cualquier combinación de los anteriores.
Para crear cualquiera de estas geometrías básicas la librería sf
contiene una serie de funciones creadoras: st_point()
, st_multipoint()
, st_linestring()
, st_polygon()
. Veamos algunos ejemplos.
7.3.1.1 Point
::st_point(c(5, 2)) # XY point sf
POINT (5 2)
::st_point(c(5, 2, 3)) # XYZ point sf
POINT Z (5 2 3)
::st_point(c(5, 2, 1), dim = "XYM") # XYM point sf
POINT M (5 2 1)
::st_point(c(5, 2, 3, 1)) # XYZM point sf
POINT ZM (5 2 3 1)
Los resultados muestran que los tipos de puntos XY (coordenadas 2D), XYZ (coordenadas 3D) y XYZM (3D con una variable adicional, normalmente precisión de medición) se crean a partir de vectores de longitud 2, 3 y 4, respectivamente. El tipo XYM debe especificarse utilizando el argumento dim
(que es la abreviatura de dimensión).
7.3.1.2 Multipoint
Para generar objetos tipo multipoint
o linestring
, trabajaremos con matrices, en lugar de con vectores. La función rbind()
facilita esta tarea.
<- sf::st_point(c(5,2))
punto1 <- sf::st_point(c(4,3))
punto2 punto1
POINT (5 2)
class(punto1)
[1] "XY" "POINT" "sfg"
plot(punto1, axes = T, xlab = "X", ylab = "Y", pch=19)
<- rbind(punto1,punto2)
matriz_puntos matriz_puntos
[,1] [,2]
punto1 5 2
punto2 4 3
class(matriz_puntos)
[1] "matrix" "array"
<- sf::st_multipoint(matriz_puntos)
multipunto multipunto
MULTIPOINT ((5 2), (4 3))
class(multipunto)
[1] "XY" "MULTIPOINT" "sfg"
par(mar = c(2,2,1,2))
plot(multipunto, axes = T, xlab = "X", ylab = "Y", pch=19)
7.3.1.3 Linestring
<- sf::st_linestring(matriz_puntos)
linea linea
LINESTRING (5 2, 4 3)
class(linea)
[1] "XY" "LINESTRING" "sfg"
par(mar = c(2,2,1,2))
plot(linea, axes = T, xlab = "X", ylab = "Y")
7.3.1.4 Multilinestring
Para generar objetos de tipo multiniestring
, polygon
, mulipolygon
o geometrycollection
trabajaremos con listas.
<- list(rbind(c(1, 5), c(5, 4), c(3, 2), c(2, 4), c(0, 4)),
lineas_list rbind(c(0, 3), c(1, 1)))
<- st_multilinestring(lineas_list)
lineas class(lineas)
[1] "XY" "MULTILINESTRING" "sfg"
par(mar = c(2,2,1,2))
plot(lineas, axes = T, xlab = "X", ylab = "Y")
7.3.1.5 Polygon
<- list(rbind(c(1, 5), c(5, 4), c(3, 2), c(2, 4), c(1, 5)))
pol1_list <- sf::st_polygon(pol1_list)
pol1 pol1
POLYGON ((1 5, 5 4, 3 2, 2 4, 1 5))
class(pol1)
[1] "XY" "POLYGON" "sfg"
par(mar = c(2,2,1,2))
plot(pol1, axes = T, xlab = "X", ylab = "Y")
Este polígono tiene 4 puntos, pero hemos puesto 5… ¿Qué ha pasado? ¿Qué pasa si quitamos el quinto punto?
7.3.1.6 Multipolygon
<- list(list(rbind(c(1, 5), c(2, 2), c(4, 1), c(4, 4), c(1, 5))),
multipolygon_list list(rbind(c(0, 2), c(1, 2), c(1, 3), c(0, 3), c(0, 2))))
<- st_multipolygon(multipolygon_list)
multipoly multipoly
MULTIPOLYGON (((1 5, 2 2, 4 1, 4 4, 1 5)), ((0 2, 1 2, 1 3, 0 3, 0 2)))
class(multipoly)
[1] "XY" "MULTIPOLYGON" "sfg"
par(mar = c(2,2,1,2))
plot(multipoly, axes = T, xlab = "X", ylab = "Y")
7.3.1.7 Geometrycollection
<- list(sf::st_multipoint(matriz_puntos),
geom_collection_list ::st_linestring(linea))
sf<- sf::st_geometrycollection(geom_collection_list)
geom_collection geom_collection
GEOMETRYCOLLECTION (MULTIPOINT ((5 2), (4 3)), LINESTRING (5 2, 4 3))
class(geom_collection)
[1] "XY" "GEOMETRYCOLLECTION" "sfg"
par(mar = c(2,2,1,2))
plot(geom_collection, axes = T, xlab = "X", ylab = "Y")
7.3.2 sfc
Como hemos visto en el bloque anterior, un objeto sfg
contiene solo una geometría simple (es, por tanto, la unidad más básica de una geometría en el paquete sf
). Una sfc
(simple feature column) es una lista de objetos sfg
(una especie de contenedor que agrupa una o más geometrías sfg
), y que además puede contener información sobre el sistema de referencia de coordenadas en uso. Para combinar dos (o más) geometrías simples en un único objeto, podemos usar la función st_sfc()
.
<- sf::st_sfc(punto1, punto2, linea, lineas, pol1, multipoly)
conjunto conjunto
Geometry set for 6 features
Geometry type: GEOMETRY
Dimension: XY
Bounding box: xmin: 0 ymin: 1 xmax: 5 ymax: 5
CRS: NA
First 5 geometries:
POINT (5 2)
POINT (4 3)
LINESTRING (5 2, 4 3)
MULTILINESTRING ((1 5, 5 4, 3 2, 2 4, 0 4), (0 ...
POLYGON ((1 5, 5 4, 3 2, 2 4, 1 5))
class(conjunto)
[1] "sfc_GEOMETRY" "sfc"
par(mar = c(2,2,1,2))
plot(conjunto, axes = T, xlab = "X", ylab = "Y")
Crea la siguiente figura:
7.3.3 sfc + CRS
Observemos el objeto creado… ¿Hay algo que te llame la atención?
Para ver qué CRS tiene asignado un objeto, usaremos la función st_crs
:
::st_crs(geom_col) sf
Coordinate Reference System: NA
Como dijimos anteriormente, es posible asignar un sistema de coordenadas de referencia al objeto sfc
. De hecho, suele ser lo habitual.
Para asignar un CRS a un objeto que aun no tiene asignado ninguno, también se usa la función st_crs
:
::st_crs(geom_col) <- 4326 sf
Para modificar el CRS de un objeto que ya tiene uno asignado, se usa la función st_transform()
:
<- sf::st_transform(geom_col, crs = 4258)
geom_col2 ::st_crs(geom_col2) sf
Coordinate Reference System:
User input: EPSG:4258
wkt:
GEOGCRS["ETRS89",
ENSEMBLE["European Terrestrial Reference System 1989 ensemble",
MEMBER["European Terrestrial Reference Frame 1989"],
MEMBER["European Terrestrial Reference Frame 1990"],
MEMBER["European Terrestrial Reference Frame 1991"],
MEMBER["European Terrestrial Reference Frame 1992"],
MEMBER["European Terrestrial Reference Frame 1993"],
MEMBER["European Terrestrial Reference Frame 1994"],
MEMBER["European Terrestrial Reference Frame 1996"],
MEMBER["European Terrestrial Reference Frame 1997"],
MEMBER["European Terrestrial Reference Frame 2000"],
MEMBER["European Terrestrial Reference Frame 2005"],
MEMBER["European Terrestrial Reference Frame 2014"],
MEMBER["European Terrestrial Reference Frame 2020"],
ELLIPSOID["GRS 1980",6378137,298.257222101,
LENGTHUNIT["metre",1]],
ENSEMBLEACCURACY[0.1]],
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["Spatial referencing."],
AREA["Europe - onshore and offshore: Albania; Andorra; Austria; Belgium; Bosnia and Herzegovina; Bulgaria; Croatia; Cyprus; Czechia; Denmark; Estonia; Faroe Islands; Finland; France; Germany; Gibraltar; Greece; Hungary; Ireland; Italy; Kosovo; Latvia; Liechtenstein; Lithuania; Luxembourg; Malta; Moldova; Monaco; Montenegro; Netherlands; North Macedonia; Norway including Svalbard and Jan Mayen; Poland; Portugal; Romania; San Marino; Serbia; Slovakia; Slovenia; Spain; Sweden; Switzerland; United Kingdom (UK) including Channel Islands and Isle of Man; Vatican City State."],
BBOX[32.88,-16.1,84.73,40.18]],
ID["EPSG",4258]]
¿Qué CRS conoces?
7.3.4 sf
Siguiendo el diagrama inicial, nos queda un último paso para crear un objeto sf
. Para ello, lo único que faltaría sería añadir un data.frame
al objeto sfc
que ya tenemos.
¿Qué información le añadirías?
<- data.frame(nombre = c("Valencia","Madrid","Barcelona","Ebro","Guadiana","España"),
data tipo = c(rep("ciudad",3), rep("rio",2), "pais"))
data
nombre tipo
1 Valencia ciudad
2 Madrid ciudad
3 Barcelona ciudad
4 Ebro rio
5 Guadiana rio
6 España pais
<- sf::st_sf(data, geom_col)
objeto_sf class(objeto_sf)
[1] "sf" "data.frame"
Ahora ya tenemos nuestro objeto sf
, el cual podemos representar gráficamente con ggplot2
:
library(ggplot2)
ggplot() +
geom_sf(data = objeto_sf)
¿Qué problemas ves en el gráfico?
Digamos que el objeto sf
que hemos creado “mezcla” información (datos) de diversa índole. Lo recomendable es tener un objeto para cada tipo de datos (puntos, líneas, polígonos) y luego usar lo que necesitemos.
library(dplyr)
<- objeto_sf %>% filter(tipo == "ciudad")
sf1 <- objeto_sf %>% filter(tipo == "rio")
sf2 <- objeto_sf %>% filter(tipo == "pais") sf3
Teniendo la información estructurada correctamente, podemos representarla mejor:
ggplot() +
geom_sf(data = sf3, fill="white") +
geom_sf(data = sf2, color="blue") +
geom_sf(data = sf1, shape=19, color="red")
7.3.5 Descomponer un objeto sf
Ya hemos visto los pasos para crear un objeto sf
pero, ¿cómo podemos extraer los datos (data.frame)? ¿y las geometrías?
Para lo primero usaremos la función st_set_geometry()
. Para lo segundo, la función st_geometry()
:
<- sf::st_set_geometry(objeto_sf, NULL)
datos class(datos)
[1] "data.frame"
datos
nombre tipo
1 Valencia ciudad
2 Madrid ciudad
3 Barcelona ciudad
4 Ebro rio
5 Guadiana rio
6 España pais
<- sf::st_geometry(objeto_sf)
geom class(geom)
[1] "sfc_GEOMETRY" "sfc"
7.4 Resumen
En este apartado hemos visto las siguientes funciones del paquete sf
:
st_point
st_multipoint
st_linestring
st_multilinestring
st_polygon
st_multipolygon
st_geometrycollection
st_sfc
st_crs
st_transform
st_sf
st_set_geometry
st_geometry
st_drop_geometry
¿Para qué sirve cada una de estas funciones?