He creado un objeto de tipo SpatialPointsDataFrame
usando el sp
paquete en R. Sin embargo, estoy confundido acerca de los @, $, . and []
operadores y cuándo usarlos para acceder a las diferentes propiedades de mi objeto. Aquí está mi código de muestra:
library(sp)
library(rgdal)
#creating a SpatialPointsDataFrame with sample points in UTM
x <- c(15.2, 15.3, 15.4, 15.5, 15.7)
y <- c(50.4, 50.2, 50.3, 50.1, 50.4)
v1 <- c(1.0, 2.0, 3.0, 4.0, 5.0)
v2 <- c("a","b","b","c","a")
attributes <- as.data.frame(cbind(v1,v2))
xy <- cbind(x,y)
locationsDD <- SpatialPointsDataFrame(xy, attributes)
proj4string(locationsDD) <- CRS("+proj=longlat")
locations <- spTransform(locationsDD, CRS("+proj=utm +zone=33"))
plot(locations)
#using the different operators: WHEN TO USE @, $ or [] ?
#all these work!
property1 <- locations$v1
property2 <- locations@data$v1
property3 <- locations@data[,"v1"]
property4 <- locations@data["v1"]
#these also work
property5 <- locations@coords
property6 <- locations@bbox
property7 <- locations@coords[,2]
#these three work only in my special case
property8 <- locations@coords[,"y"]
property9 <- locations$x
property10 <- locations$y
#these don't work: $ operator is invalid for atomic vectors
property11 <- locations@coords$x
property12 <- locations@coords$y
¿Alguien podría ayudarme, cuándo usar los @, $, []
operadores? Cuando intento leer la documentación ?SpatialPointsDataFrame
, puedo ver las diferentes propiedades como coords
o bbox
pero estoy confundido sobre qué operador @, $, []
usar para acceder a ellas o modificarlas.
R
sintaxis, no es particular delsp
paquete o sus objetos.R
se instala con un tutorial: comience allí en su investigación. La Web y los medios impresos ofrecen una gran cantidad de recursos adicionales para el aprendizajeR
.Respuestas:
Los datos espaciales sp son objetos de clase S4 y están formados por ranuras (llamadas usando @) que contienen componentes de la clase de entidad espacial que se está representando (por ejemplo, @data contiene atributos, @coords contienen pares de coordenadas, etc.). Puede devolver los nombres de las ranuras de nivel superior utilizando slotNames (), pero no es recursivo y no devolverá nombres de ranuras anidadas para objetos de clase de polígono. Cada ranura puede contener una clase de objeto diferente y, antes de operar en ella, debe verificarse usando str () o class (). La ranura @data siempre es un objeto data.frame y @coords es una matriz, mientras que @polygons es un objeto de lista con ranuras adicionales (labpt, area, hole, ringDir y coords).
Los espacios disponibles y la organización de ellos dependen del tipo de clase de entidad que se represente. Los objetos SpatialPointsDataFrame son los más básicos, mientras que los objetos SpatialPolygonsDataFrame tienen anidamiento (como se ve arriba). Esta estructura anidada, que representa cada polígono, debe tenerse en cuenta utilizando algo como sapply para operar en cada objeto de lista (polígono).
Aquí hay un ejemplo que usa sapply para devolver el área de cada polígono iterando a través de los "polígonos" y luego las ranuras anidadas de "área".
En el caso de los objetos poligonales, dado que se almacenan como una lista para cada polígono, también puede usar la indexación de listas. Aquí hay un ejemplo para devolver el primer polígono (que da como resultado un objeto de clase "Polígono" y no SpatialPolygonsDataFrame):
En versiones más recientes de sp, los desarrolladores han comenzado, en algunos casos, a eliminar la necesidad de llamar directamente a la ranura @data.
Por ejemplo, para indexar @data anteriormente:
y ahora:
Sin embargo, como se indicó anteriormente, este no es el caso para las otras ranuras (por ejemplo, coordenadas, polígonos, etc.). En cuanto a cuándo usar [] o $, esto todavía depende del tipo de operación. Los corchetes "[]" se pueden usar para llamar a un nombre en un marco de datos, pero se usan principalmente para indexar, mientras que $ se usa específicamente para llamar a una columna en un marco de datos. La razón por la que una llamada "indirecta" a un nombre de columna funciona es que los desarrolladores han agregado funcionalidad para permitir una búsqueda recursiva a través del objeto sp. Sin embargo, para evitar conflictos de nombres (como en su ejemplo; tener columnas x, y en su marco de datos entraría en conflicto con los nombres x, y en los nombres de la matriz @coord) hay alguna comprobación de consistencia interna que explica por qué esto solo funciona en algunos instancias.
Una característica conveniente es que puede subconjugar un objeto espacial a través de un índice de fila. Aquí estoy subconjustando los primeros 10 objetos.
O, alternativamente, una muestra aleatoria (n = 10) usando un vector de índice de fila.
Comprender la indexación y cómo usar corchetes es algo muy importante al escribir código R.
Editar (24/03/2017): Tenga en cuenta que la clase de entidad simple (sf), siguiendo el estándar GeoJSON, probablemente se convertirá en el nuevo estándar para objetos espaciales en R. Puede leer una descripción detallada de esta clase en el CRAN sf página web simple Características de R .
fuente
SpatialPointsDataFrame
no solo se pueden recuperar las columnas @data, sino también las columnas @coords con el$
operador sin la necesidad de llamar a la ranura @coords. Entoncessdat@coords$easting
da el mismo resultado quesdat$easting
.colnames(locations@coords)
devuelve[1] "x" "y"
perocolnames(locations@data)
vuelve[1] "v1" "v2"
. ¿Quizás el comportamiento depende de qué función se utilizó para crear el SpatialPointsDataFrame?sdat@coords$easting
no funciona porque sdat @ coords es una matriz. Perosdat@coords[,"easting"]
es equivalente asdat@coords[,1]
y asdat$easting
.Deberías intentar
str(locations)
aclarar esto.por ejemplo, estos son correctos:
Y este
property1 <- locations$v1
funciona, porque hace referencia a la ubicación interna de data.frame, @datafuente
str(locations)
me dio algunas buenas pistas. Ahora entiendo que@
se utiliza para "ranura de una clase". Pero todavía no entiendo por quéproperty9 <- locations$x
funciona cuandonames(locations)
no contiene ninguna columna llamadax
SpatialPointsDataFrame
usa el objeto para acceder a las coordenadas con el$
operador. Pero al menos me siento más cómodo al usarlo ahora. Ejecuté el siguiente código:colnames(locations@coords) <- c("easting","northing")
Después de ejecutarlo,locations$easting
me da el vector de coordenadas xy me da el vector de coordenadas ylocations$northing
.@coords
matriz deSpatialPointsDataFrame
depende de cómoSpatialPointsDataFrame
se creó el objeto. Método uno:coordinates(sdat) <- x ~ y
cambiará el nombre de las columnas a"coords.x1", "coords.x2"
. Método dos:sdat <- SpatialPointsDataFrame(xy, attributes)
preservará los nombres de columna originales de laxy
matriz.