La abreviatura de la librería sf significa “simple features” o “caracteristicas simples”, la cual se refiere al código estandar abierto que los programas SIG utilizan para trabajar con datos espaciales y está compuesta principalmente por: puntos, líneas, poligonos, multipunto, multilínea, etc.
Una de las limitaciones es que actualmente el paquete sf no tiene por el momento soporte para datos raster.
Su principal diferencia con otros paquetes espaciales como: sp, rgdal y rgeos, es que sf se basa en un marco de datos para su manipulación, por lo que su manejo es mucho más intuitivo y permite aprovechar los beneficios ofrecidos por framework de tidyverse.
Un objeto sf contiene al menos una geometría que incluye uno o más puntos, líneas o polígonos, un CRS (Sistema de referencia de coordenadas) y atributos asociados a cada elemento geográfico.
Las unidades básicas de los objetos sf se denominan sfg (sf objects), los cuales contienen las coordenadas, la dimensión, y el tipo de geometría de una única característia espacial (por lo cual aún no podrían considerarse como objeto georeferenciado). El paquete sf admite siete tipos únicos de sfg:
(st_point())
FALSE X Y
FALSE 1 -78.49396 -0.211751
pointsC2 <- st_point(c(-78.492162, -0.206055))
pointsC3 <- st_point(c(-78.488182, -0.205250))
pointsC4 <- st_point(c(-78.485296,-0.208694))
pointsC5 <- st_point(c(-78.4865284,-0.2093347))
pointsC6 <- st_point(c(-78.4875284,-0.2093347))
pointsC7 <- st_point(c(-78.490855,-0.210689))
pointsC8 <- st_point(c(-78.4921097,-0.2101194))
plot(pointsC1, main='Puntos1')(st_multipoint())
MultpointsC1 <- st_multipoint(rbind(c(-78.493957, -0.211751),
c(-78.492162, -0.206055),
c(-78.488182, -0.205250),
c(-78.485296,-0.208694),
c(-78.4865284,-0.2093347),
c(-78.4875284,-0.2093347),
c(-78.490855,-0.210689),
c(-78.4921097,-0.2101194)))
plot(MultpointsC1, main='MultiPuntos1')FALSE [1] "XY" "MULTIPOINT" "sfg"
FALSE 'XY' num [1:8, 1:2] -78.5 -78.5 -78.5 -78.5 -78.5 ...
FALSE NULL
FALSE X Y L1
FALSE [1,] -78.49396 -0.2117510 1
FALSE [2,] -78.49216 -0.2060550 1
FALSE [3,] -78.48818 -0.2052500 1
FALSE [4,] -78.48530 -0.2086940 1
FALSE [5,] -78.48653 -0.2093347 1
FALSE [6,] -78.48753 -0.2093347 1
FALSE [7,] -78.49085 -0.2106890 1
FALSE [8,] -78.49211 -0.2101194 1
FALSE num [1:8, 1:3] -78.5 -78.5 -78.5 -78.5 -78.5 ...
FALSE - attr(*, "dimnames")=List of 2
FALSE ..$ : NULL
FALSE ..$ : chr [1:3] "X" "Y" "L1"
(st_linestring())
(lines1 <- st_linestring( rbind(c(-78.493957, -0.211751),
c(-78.492162, -0.206055),
c(-78.488182, -0.205250),
c(-78.485296,-0.208694),
c(-78.4865284,-0.2093347),
c(-78.4875284,-0.2093347),
c(-78.490855,-0.210689),
c(-78.4921097,-0.2101194)
#,c(-78.493957, -0.211751) # lineas cerradas pero no es poligono
) ))
plot(lines1, main='Lineas1')(st_multilinestring())
(lines1 <- st_multilinestring( list(rbind(c(-78.493957, -0.211751),
c(-78.492162, -0.206055),
c(-78.488182, -0.205250),
c(-78.485296,-0.208694),
c(-78.4865284,-0.2093347),
c(-78.4875284,-0.2093347),
c(-78.490855,-0.210689),
c(-78.4921097,-0.2101194)
#,c(-78.493957, -0.211751) multilines
)) ))
plot(lines1, main='Multilineas1')(st_polygon())
poligon1 <- st_polygon(list((rbind(c(-78.493957, -0.211751),
c(-78.492162, -0.206055),
c(-78.488182, -0.205250),
c(-78.485296,-0.208694),
c(-78.4865284,-0.2093347),
c(-78.4875284,-0.2093347),
c(-78.490855,-0.210689),
c(-78.4921097,-0.2101194),
c(-78.493957, -0.211751)))))
print(poligon1)
plot(poligon1, main='Poligono1')(st_multipolygon())
## recordar que los poligonos son polilineas donde la ultima se une con la primera
outer = matrix(c(0,0,10,0,10,10,0,10,0,0),ncol=2, byrow=TRUE)
hole1 = matrix(c(1,1,1,2,2,2,2,1,1,1),ncol=2, byrow=TRUE)
hole2 = matrix(c(5,5,5,6,6,6,6,5,5,5),ncol=2, byrow=TRUE)
pol1 = list(outer, hole1, hole2)
pol2 = list(outer + 12, hole1 + 12)
pol3 = list(outer + 24)
mp = list(pol1,pol2,pol3)
(mp1 = st_multipolygon(mp))
plot(mp1)(cualquier combinacion de los otros 6 tipos de sfg)
mp1_centroid <- st_geometrycollection(list(poligon1,
pointsC1,pointsC2,pointsC3,pointsC4,
pointsC5,pointsC6,pointsC7,pointsC8))
plot(mp1_centroid, main='GEOMETRYCOLLECTION')Luego de definir los objetos sf, estos aun no son objetos espaciales dado que carecen de un CRS. Al otorgar un CRS a un objeto sf ahora tenemos un sfc, para lo cual usamos la función st_sfc().
st_sfc toma uno o más sfg y opcionalmente un atributo crs, que puede ser un código EPSG o una string Proj4string. En este caso, usamos EPSG 4236, que corresponde a las coordenadas de latitud y longitud en el elipsoide WGS84. Para poder acceder al CRS se puede usar la función st_crs
FALSE Geometry set for 1 feature
FALSE geometry type: GEOMETRYCOLLECTION
FALSE dimension: XY
FALSE bbox: xmin: -78.49396 ymin: -0.211751 xmax: -78.4853 ymax: -0.20525
FALSE geographic CRS: WGS 84
FALSE [1] "sfc_GEOMETRYCOLLECTION" "sfc"
Procesamiento de atributos de datos espaciales según el enfoque TIDYVERSE
A comparación de otras áreas de ciencia de datos, el análisis de datos espaciales utilizando tidyverse está relativamente poco desarrollado debido a que los tipos de objetos espaciales existentes trabadados por librerías como: sp, rgdal y rgeos, no trabajan fácilmente con este enfoque. No obstante, por medio del paquete sf progresivamente se está disminuyendo esta no compatibilidad.
El aprender el enfoque tidyverse no solo permite tratar datos espaciales sino que también permite trabajar con sus atributos, con lo cual, el tiempo invertido en estudiar esto nos dará habilidades que nos servirán ampliamente.
En el mayor número de casos, más que tratar los datos espaciales, se necesita saber como procesar sus atributos, sin afectar la geometría de los datos espaciales. Esto es lo que aprenderemos en este apartado.
En otros casos es necesario manipular los atributos para encontrar coordenadas que permitan ubicarlas en el espacio o procesar las que se disponen para mejorarlas o curarlas.
Funciones para tratamiento de datos tanto espaciales como no espaciales
Existen cuatro funciones o verbos principales para tratar datos en general desde el enfoque tidyverse: select(), filter(), mutate(), arrange().
Estas fuciones estan desarrolladas en lenguage C++ dado una eficiencia computacional notable y pertenecen a la librería dplyr
En aspectos generales las cuatro funciones se basan en el funcionamiento de SQL, para facilitar el aprendizaje.
select(): Permite extraer las variables de interés de un set de datos. En el caso de los datos espaciales, conserva la geometría.
Nota: Esta función necesita utilizar prefijo dplyr::. Esto sucede dado que los paquetes raster y dplyr tienen una función llamada select(). Al utilizar ambos paquetes, se necesita evitar la ambigüedad, pasando a utilizarse con el nombre de la función de formato largo, con el prefijo del nombre del paquete y dos puntos dobles: dplyr::select().
filter(): permite obtener filas por medio de pruebas lógicas. Ya sea “==”, “!=”, “>”, “>=”, “<”, “<=”, “&” y “|”, mismas que conservan la geometría.
mutate(): permite aumentar o crear más variables, conservando la geometría.
arrage(): permite ordenar las observaciones, conservando la geometría.
Otras funciones relevantes
pull(): es similar a select(), no obstante, elimina la geometría, ya que convierte la variable en vector.
slice(): permite obtener filas por medio de selecciones en base a posiciones, conservando la geometría.
left_join(): permite unir dos tablas por medio de una variable clave, consevardo las IDs que existan en la tabla de la parte izquierza. NO se perderá las geometrías, siempre y cuando la tabla espacial sea la prioridad.
inner_join(): permite unir dos tablas por medio de una variable clave, consevardo las IDs que existan en las dos tablas. NO se perderá las geometrías, siempre y cuando la tabla espacial sea la prioridad.
Finalmente, la indexación también es una metodología por la cual se puede tratar datos espaciales, en cierto grado puede ser mucho más rápida que tidyverse, dado que es nativa de R, aunque debe tratarse con cuidado.
La librería ggplot2 al igual que la librería dplyr pertenece al metapaquete tidyverse y nos permite desarrollar gráficos ilustrativos amplios.
Existen tres componentes básicos:
Data: constituye el data set a analizarse.
Aesthetics: de todo el data set determina las variables a gráficarse, es decir, x = variable1 y y = variable2. Además, permite darle estética a estos elementos como: color, difuminación, forma, entre otros atributos más.
Geometry: este componente representa el tipo de gráfico a desarrollarse, por ejemplo, un gráfico de puntos geom_point(), un histograma geom_histogram() o un mapa o dato espacial por medio de geom_sf(). También permite colocar etiqutas o texto.
Facets: permite tener varios gráficos separados hasta por dos variables de interés.
Statistics: a la hora de gráficar es necesario saber que escalas usar, si la variable presenta alta disperción utilizar una transformación logarítmica, cuadrática u otra, un muestreo o un procesamiento para que sea más interpretable.
Coordinates: permite saber que tipo de plano se utilizará para representar el gráfico, en su mayoría es el plano cartesiano.
Theme: permite personalizar la organización del gráfico.
Paleta de colores Permite dar estética a los gráficos tanto espaciales como no espaciales. - http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf
Ejemplos
Leaflet es una biblioteca de JavaScript de código abierto para mapas interactivos y tiene varias funciones de mapeo integrables con R.
Leaflet está diseñado teniendo en cuenta la simplicidad , el rendimiento y la facilidad de uso. Funciona de manera eficiente en todas las principales plataformas móviles y de escritorio, se puede ampliar con muchos complementos , tiene una API hermosa, fácil de usar y bien documentada, y un código fuente simple y legible al que es un placer contribuir.
Las operaciones espaciales son una parte vital de la geocomputación. Este sección mostrará cómo los objetos espaciales pueden modificarse de diversas maneras según su ubicación y forma.
A las relaciones espaciales entre sfg o sfc se denominan relaciones topológicas y se utilizan para obtener subconjuntos espaciales. Las relaciones per se determinan el tipo de subconjunto que se va a seleccionar, por ejemplo: los coques, cruces o las intersecciones.
Cuando realizamos este tipo de operaciones se obtienen nuevos objetos denominados sgbp, que siginifica un objeto de predicado binario de geometría dispersa, el cual se representa a través de una lista.
a_poly = st_polygon(list(rbind(c(-1, -1),
c(1, -1),
c(1, 1),
c(-1, -1))))
a = st_sfc(a_poly)
# create a line
l_line = st_linestring(x = matrix(c(-1, -1, -0.5, 1), ncol = 2))
l = st_sfc(l_line)
# create points
p_matrix = matrix(c(0.5, 1, -1, 0, 0, 1, 0.5, 1), ncol = 2)
p_multi = st_multipoint(x = p_matrix)
# COERCION DE DATOS ESPACIALES
p = st_cast(st_sfc(p_multi), "POINT")
etiquetas <- as.data.frame(st_coordinates(p))
etiquetas$etiq <- c(1,2,3,4)
a %>%
ggplot() +
geom_sf() +
geom_sf(data = p) +
geom_sf(data = l) +
geom_text(data = etiquetas, aes(X+0.05,Y+0.05,label = etiq))Existen varias preguntas asociadas a este conjunto de sfc, por ejemplo:
st_intersects()
Este es un operador de subconjunto espacial de valor predeterminado que devuelve TRUE para muchos tipos de relaciones espaciales, incluidos toques, cruces y pertenencias.
FALSE Sparse geometry binary predicate list of length 4, where the predicate was `intersects'
FALSE 1: 1
FALSE 2: 1
FALSE 3: (empty)
FALSE 4: (empty)
# equivale a la version original solo que se especifica en sparse como TRUE
st_intersects(p,a,sparse = TRUE)FALSE Sparse geometry binary predicate list of length 4, where the predicate was `intersects'
FALSE 1: 1
FALSE 2: 1
FALSE 3: (empty)
FALSE 4: (empty)
FALSE [1] "sgbp" "list"
La función como resultado devuelve 1 para los dos primeros puntos y un resultado negativo (representado por un vector vacío) para los dos últimos. El resultado como se puede obserbar se presenta en forma de una lista de vectores.
Una característica relevante es que la salida de matriz dispersa solo registra una relación si existe, lo cual reduce los requisitos de memoria de las operaciones topológicas en objetos de múltiples características.
Por otra parte, también se puede devolver una matriz densa que consta de TRUE o FALSE para cada combinación de características cuando sparse = FALSE.
# al especificar el argumento sparse como FALSE tenemos una matriz de resultados
st_intersects(p,a,sparse = FALSE) FALSE [,1]
FALSE [1,] TRUE
FALSE [2,] TRUE
FALSE [3,] FALSE
FALSE [4,] FALSE
FALSE [1] "matrix" "array"
Nota: Tenemos que tener en cuenta que st_intersects() retorna TRUE aunque solo toque el polígono a, esto sucede dado que intersects es una operación topológica ‘catch-all’ que identifica muchos tipos de relación espacial.
st_disjoint()
Lo contrario de st_intersects() es st_disjoint(), que devuelve solo objetos que no se relacionan espacialmente de ninguna manera con el objeto de selección.
FALSE [,1]
FALSE [1,] FALSE
FALSE [2,] FALSE
FALSE [3,] TRUE
FALSE [4,] TRUE
FALSE [1] FALSE FALSE TRUE TRUE
Nota: [, 1] convierte el resultado en un vector.
st_within()
Devuelve TRUE solo para los objetos que están completamente dentro del objeto de selección.
## caso en el que solo toma los puntos que estan dentro de un objeto de seleccion
st_within(p, a, sparse = FALSE)[, 1]FALSE [1] TRUE FALSE FALSE FALSE
st_touches()
Devuelve TRUE solo para los objetos que se tocan.
FALSE [1] FALSE TRUE FALSE FALSE
¿Qué pasa con las funciones que no se cochan, pero casi chocan el objeto de selección?
st_is_within_distance()
Estos se pueden seleccionar usando st_is_within_distance(), que tiene un argumento adicional que considera la distancia, el cual se puede utilizar para establecer qué tan cerca deben estar los objetos de destino antes de seleccionarlos.
# ahora pongamos distancias para poder encontrar pertenecia
sel = st_is_within_distance(p, a, dist = 0.9)
lengths(sel) > 0FALSE [1] TRUE TRUE FALSE TRUE