Tengo un SpatialPointsDataFramecon algunos datos adicionales. Me gustaría extraer esos puntos dentro de un polígono y, al mismo tiempo, preservar el SPDFobjeto y sus datos correspondientes.
Hasta ahora he tenido poca suerte y he recurrido a la coincidencia y la fusión a través de una ID común, pero esto solo funciona porque tengo datos cuadriculados con IDS individuales.
Aquí hay un ejemplo rápido, estoy buscando puntos dentro del cuadrado rojo.
library(sp)
set.seed(357)
pts <- data.frame(x = rnorm(100), y = rnorm(100), var1 = runif(100), var2 = sample(letters, 100, replace = TRUE))
coordinates(pts) <- ~ x + y
class(pts)
plot(pts)
axis(1); axis(2)
ply <- matrix(c(-1,-1, 1,-1, 1,1, -1,1, -1,-1), ncol = 2, byrow = TRUE)
ply <- SpatialPolygons(list(Polygons(list(Polygon(ply)), ID = 1)))
ply <- SpatialPolygonsDataFrame(Sr = ply, data = data.frame(polyvar = 357))
plot(ply, add = TRUE, border = "red")
El enfoque más obvio sería usar over, pero esto devuelve los datos del polígono.
> over(pts, ply)
polyvar
1 NA
2 357
3 357
4 NA
5 357
6 357

Respuestas:
De la
sp::overayuda:Entonces, si convierte su
SpatialPolygonsDataFrameaSpatialPolygons, obtiene un vector de índices y puede subconjugar sus puntos enNA:Para los que dudan, aquí hay evidencia de que la sobrecarga de conversión no es un problema:
Dos funciones: primero el método de Jeffrey Evans, luego mi original, luego mi conversión pirateada, luego una versión basada en
gIntersectsla respuesta de Josh O'Brien:Ahora, para un ejemplo del mundo real, he dispersado algunos puntos aleatorios sobre el
columbusconjunto de datos:Se ve bien
Verifique que las funciones estén haciendo lo mismo:
Y corra 500 veces para la evaluación comparativa:
Según mi intuición, no es una gran sobrecarga, de hecho, podría ser menos una sobrecarga que convertir todos los índices de fila en caracteres y viceversa, o ejecutar na.omit para obtener valores perdidos. Lo que incidentalmente conduce a otro modo de falla de la
evansfunción ...Si una fila del marco de datos de polígonos es todo
NA(lo cual es perfectamente válido), entonces la superposición conSpatialPolygonsDataFramepuntos en ese polígono producirá un marco de datos de salida con todos losNAs, queevans()luego caerán:PERO
gIntersectses más rápido, incluso teniendo que barrer la matriz para verificar las intersecciones en R en lugar de en el código C. Sospecho que son lasprepared geometryhabilidades de GEOS, la creación de índices espaciales, sí, conprepared=FALSEesto lleva un poco más de tiempo, unos 5,5 segundos.Me sorprende que no haya una función para devolver directamente los índices o los puntos. Cuando escribí hace
splancs20 años, las funciones de punto en el polígono tenían ambas ...fuente
spproporciona una forma más corta para seleccionar entidades basadas en la intersección espacial, siguiendo el ejemplo de OP:a partir de:
Detrás de escena esto es la abreviatura de
Lo que hay que tener en cuenta es que hay un
geometrymétodo que elimina atributos:overcambia el comportamiento si su segundo argumento tiene atributos o no (esto fue la confusión de OP). Esto funciona en todas las clases de Spatial *sp, aunque algunosovermétodos lo requierenrgeos, vea esta viñeta para obtener detalles, por ejemplo, el caso de coincidencias múltiples para polígonos superpuestos.fuente
Estabas en el camino correcto con más. Los nombres de fila del objeto devuelto corresponden al índice de fila de los puntos. Puede implementar su enfoque exacto con solo unas pocas líneas de código adicionales.
fuente
¿Es esto lo que buscas?
Una nota, en edición: la llamada de ajuste a
apply()es necesaria para que esto funcione conSpatialPolygonsobjetos arbitrarios , que posiblemente contengan más de una función de polígono. Gracias a @Spacedman por animarme a demostrar cómo aplicar esto al caso más general.fuente
plytiene más de una característica, porquegIntersectsdevuelve una matriz con una fila para cada característica. Probablemente pueda barrer las filas para obtener un valor VERDADERO.apply(gIntersects(pts, ply, byid=TRUE), 2, any). De hecho, seguiré adelante y cambiaré la respuesta a eso, ya que abarca el caso de un solo polígono también.any. Eso podría ser marginalmente más rápido que la versión que acabo de comparar.obrienyrowlings2corre cuello y cuello, conobrienquizás un 2% más rápido.ppdebe tener unIDque indique en qué polígono se encuentran los puntos.Aquí hay un posible enfoque usando el
rgeospaquete. Básicamente, hace uso de lagIntersectionfunción que le permite intersecar dosspobjetos. Al extraer los ID de esos puntos que se encuentran dentro del polígono, puede subconjugar su originalSpatialPointsDataFramey conservar todos los datos correspondientes. El código casi se explica por sí mismo, pero si tiene alguna pregunta, ¡no dude en preguntar!fuente
tmpserpts.intersect? Además, analizar los dimombres devueltos de esa manera depende del comportamiento indocumentado.tmp, olvidó eliminarlo al terminar el código. Además, tienes razón al analizar eldimnames. Esta fue una especie de solución rápida para proporcionar al interlocutor una respuesta rápida, y seguramente hay enfoques mejores (y más universales), por ejemplo el suyo: -)Hay una solución extremadamente simple usando la
spatialEcobiblioteca.Comprueba el resultado:
fuente