Proprietà e operatori SpatialPointsDataFrame in R


14

Ho creato un oggetto di tipo SpatialPointsDataFrameusando il sppacchetto in R. Tuttavia, sono confuso sugli @, $, . and []operatori e su quando usarli per accedere alle diverse proprietà del mio oggetto. Ecco il mio codice di esempio:

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

Qualcuno potrebbe aiutarmi, quando usare gli @, $, []operatori? Quando provo a leggere la documentazione, ?SpatialPointsDataFramevedo le diverse proprietà come coordso bboxma sono confuso quale operatore @, $, []utilizzare per accedervi o modificarle.


1
Poiché questa è davvero una domanda sulla Rsintassi, non è particolare per il sppacchetto o i suoi oggetti. Rè installato con un tutorial: inizia lì nella tua ricerca. Il Web e i supporti di stampa offrono numerose risorse aggiuntive per l'apprendimento R.
whuber

Risposte:


21

I dati spaziali spaziali sono oggetti di classe S4 e sono costituiti da slot (chiamati usando @) che contengono componenti della classe di caratteristiche spaziali rappresentata (ad esempio, @data contiene attributi, @coords contiene coppie di coordinate, ecc ...). È possibile restituire i nomi degli slot di livello superiore utilizzando slotNames () ma non è ricorsivo e non restituirà i nomi degli slot nidificati per gli oggetti della classe poligonale. Ciascuno slot può contenere una diversa classe di oggetti e, prima di operare su di essa, deve essere verificato usando str () o class (). Lo slot @data è sempre un oggetto data.frame e @coords è una matrice mentre @polygons è un oggetto elenco con slot aggiuntivi (labpt, area, hole, ringDir e coords).

Gli slot disponibili e la loro organizzazione dipende dal tipo di classe di caratteristiche che viene rappresentata. Gli oggetti SpatialPointsDataFrame sono i più elementari, mentre gli oggetti SpatialPolygonsDataFrame hanno un annidamento (come visto sopra). Questa struttura nidificata, che rappresenta ciascun poligono, deve essere spiegata usando qualcosa come sapply per operare su ciascun oggetto della lista (poligono).

Ecco un esempio che utilizza sapply per restituire l'area per ciascun poligono ripetendo i "poligoni", quindi gli slot "area" nidificati.

sapply(slot(sdat, 'polygons'), function(i) slot(i, 'area')) 

Nel caso di oggetti poligonali, poiché sono memorizzati come elenco per ciascun poligono, è possibile utilizzare in alternativa l'indicizzazione degli elenchi. Ecco un esempio per restituire il primo poligono (risultante in un oggetto di classe "Poligono" e non in SpatialPolygonsDataFrame):

sdat@polygons[[1]]

Nelle versioni più recenti di sp gli sviluppatori hanno iniziato, in alcuni casi, a rimuovere la necessità di chiamare direttamente lo slot @data.

Ad esempio, per indicizzare @data in precedenza:

sdat@data[sdat@data$att >= 0.5 ,]  

e adesso:

sdat[sdat$att >= 0.5 ,]

Tuttavia, come precedentemente indicato, questo non è il caso degli altri slot (ad es. Coordinate, poligoni, ecc ...). Per quanto riguarda quando usare [] o $ questo dipende ancora dal tipo di operazione. Le parentesi "[]" possono essere usate per chiamare un nome in un dataframe ma sono usate principalmente per l'indicizzazione mentre $ è usato specificamente per chiamare una colonna in un dataframe. Il motivo per cui una chiamata "indiretta" al nome di una colonna funziona perché gli sviluppatori hanno aggiunto funzionalità per consentire una ricerca ricorsiva attraverso l'oggetto sp. Tuttavia, per evitare conflitti di nomi (come nel tuo esempio; avere colonne x, y nel tuo frame di dati sarebbe in conflitto con i nomi x, y nei nomi della matrice @coord) c'è un certo controllo interno di coerenza che spiega perché questo funziona solo in alcuni le istanze.

Una caratteristica utile è che puoi sottoinsieme un oggetto spaziale attraverso un indice di riga. Qui sto sottoponendo i primi 10 oggetti.

sub.sdat <- sdat[1:10,] 

Oppure, in alternativa, un campione casuale (n = 10) usando un vettore indice di riga.

rs.sdat <- sdat[sample(1:nrow(sdat), 10),]

Comprendere l'indicizzazione e come usare le parentesi è una cosa molto importante nella scrittura del codice R.

Modifica (24/03/2017): Nota che la classe caratteristica semplice (sf), seguendo lo standard GeoJSON, diventerà probabilmente il nuovo standard per gli oggetti spaziali in R. Puoi leggere una descrizione dettagliata di questa classe sul CRAN sf sito web semplice Caratteristiche per R .


Grazie per una spiegazione dettagliata di ciò che sta accadendo dietro le quinte. Sembra che SpatialPointsDataFramenon solo le colonne @data, ma anche le colonne @coords possano essere recuperate con l' $operatore senza la necessità di chiamare lo slot @coords. Quindi sdat@coords$eastingdà lo stesso risultato di sdat$easting.
jirikadlec2,

Sembra che tu stia chiamando una colonna in <at> dati. Questo non è lo stesso dello slot <at> coords. Noterai che se chiami colnames (sdat <at> coords) restituirai i nomi delle colonne della matrice: "coords.x1", "coords.x2". Non è necessario mantenere le coordinate nel dataframe e, poiché è duplicato, una vita di memoria.
Jeffrey Evans,

No. Non sto chiamando la colonna in <at> dati. Utilizzando SpatialPointsDataFrame dal mio script di esempio, colnames(locations@coords)ritorna [1] "x" "y"ma colnames(locations@data)ritorna [1] "v1" "v2". Forse il comportamento dipende da quale funzione è stata utilizzata per creare SpatialPointsDataFrame?
jirikadlec2,

In realtà ho un errore nel mio primo commento. sdat@coords$eastingnon funziona perché sdat @ coords è una matrice. Ma sdat@coords[,"easting"]equivale a sdat@coords[,1]e a sdat$easting.
jirikadlec2,

Un avvertimento, colnames () viene utilizzato per restituire i nomi di colonna in una matrice mentre, names () restituirà NULL. Sebbene sia names () che colnames () funzioneranno su un oggetto dataframe come <at> data. Il modo migliore per recuperare i dati dalla matrice <at> coord è indicizzarli: sdat <at> coords [, 1] o con il nome della colonna sdat <at> coords [, "coords.x1"] ma come hai notato $ fa non funziona perché è un oggetto matrice.
Jeffrey Evans,

4

Dovresti provare str(locations)a chiarire questo.

ad esempio, questi sono corretti:

property2 <- locations@data$v1
property5 <- locations@coords
property6 <- locations@bbox
property7 <- locations@coords[,"x"]
property8 <- locations@coords[,2]

E questo property1 <- locations$v1funziona, perché fa riferimento a data.frame all'interno della posizione, @data


str(locations)mi ha dato dei buoni suggerimenti. Ora capisco che @è usato per "slot di una classe". Ma ancora non capisco perché property9 <- locations$xnames(locations)x
funzioni

1
Quando si crea SpatialPointDataFrame, si assegnano xey come nomi di coordinate. Se guardi locations @ coords puoi vedere la matrice con le coordinate. Inoltre, se provi a creare una nuova colonna in @data con il nome "x", non puoi, perché è già utilizzato come nome della coordinata.
Guillermo Olmedo,

Non riesco ancora a capire quale tipo di "magia" l' SpatialPointsDataFrameoggetto utilizza per accedere alle coordinate con l' $operatore. Ma almeno mi sento più a mio agio nell'usarlo ora. Ho eseguito il seguente codice: colnames(locations@coords) <- c("easting","northing") Dopo averlo eseguito, locations$eastingmi dà il vettore della coordinata x e locations$northingmi dà il vettore della coordinata y.
jirikadlec2,

Penso che in qualche modo R consideri le due colonne per le coordinate come altre due colonne della parte del frame di dati di SpatialPointsDataFrame. Ecco perché puoi avere una colonna con lo stesso nome all'interno dello slot @data
Guillermo Olmedo,

1
Sembra che la denominazione delle colonne nella @coordsmatrice del SpatialPointsDataFramedipenda da come è SpatialPointsDataFramestato creato l' oggetto. Metodo 1: coordinates(sdat) <- x ~ yrinominerà le colonne in "coords.x1", "coords.x2". Metodo due: sdat <- SpatialPointsDataFrame(xy, attributes)preserverà i nomi delle colonne originali dalla xymatrice.
jirikadlec2,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.