Properti SpatialPointsDataFrame dan operator di R

14

Saya telah membuat objek tipe SpatialPointsDataFramemenggunakan sppaket di R. Namun, saya bingung tentang @, $, . and []operator dan kapan menggunakannya untuk mengakses properti yang berbeda dari objek saya. Berikut ini contoh kode saya:

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

Adakah yang bisa membantu saya, kapan harus menggunakan @, $, []operator? Ketika saya mencoba membaca dokumentasi ?SpatialPointsDataFramesaya dapat melihat properti yang berbeda seperti coordsatau bboxtetapi saya bingung operator mana yang @, $, []akan digunakan untuk mengaksesnya atau memodifikasinya.

jirikadlec2
sumber
1
Karena ini benar-benar pertanyaan tentang Rsintaks, itu tidak khusus untuk sppaket atau objeknya. Rdiinstal dengan tutorial: mulailah dari sana dalam penelitian Anda. Web dan media cetak menawarkan banyak sumber daya tambahan untuk belajar R.
whuber

Jawaban:

21

Data sp spasial adalah objek kelas S4 dan terdiri dari slot (disebut dengan menggunakan @) yang berisi komponen kelas fitur spasial yang diwakili (misalnya, @ data mengandung atribut, @ coords berisi pasangan koordinat, dll ...). Anda dapat mengembalikan nama slot tingkat atas menggunakan slotNames () tetapi tidak rekursif dan tidak akan mengembalikan nama slot bersarang untuk objek kelas poligon. Setiap slot dapat berisi kelas objek yang berbeda dan, sebelum mengoperasikannya, harus diperiksa menggunakan str () atau class (). Slot @data selalu merupakan objek data.frame dan @coords adalah matriks sedangkan @polygons adalah objek daftar dengan slot tambahan (labpt, area, hole, ringDir dan coords).

Slot dan organisasi yang tersedia tergantung pada jenis kelas fitur yang diwakili. Objek SpatialPointsDataFrame adalah yang paling dasar, sedangkan objek SpatialPolygonsDataFrame bersarang (seperti yang terlihat di atas). Struktur bersarang ini, mewakili setiap poligon, harus dipertanggungjawabkan menggunakan sesuatu seperti sapply untuk beroperasi pada setiap objek daftar (poligon).

Berikut adalah contoh yang menggunakan sapply untuk mengembalikan area untuk setiap poligon dengan mengulangi melalui "poligon" lalu, slot, area "bersarang".

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

Dalam kasus objek poligon, karena mereka disimpan sebagai daftar untuk setiap poligon, Anda dapat menggunakan pengindeksan daftar. Berikut ini adalah contoh untuk mengembalikan poligon pertama (menghasilkan objek kelas "Poligon" dan bukan SpatialPolygonsDataFrame):

sdat@polygons[[1]]

Dalam versi yang lebih baru dari sp pengembang telah memulai, dalam beberapa kasus, menghapus keharusan memanggil slot @data secara langsung.

Misalnya, untuk mengindeks @ data Anda sebelumnya:

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

dan sekarang:

sdat[sdat$att >= 0.5 ,]

Namun, seperti yang ditunjukkan sebelumnya, ini bukan kasus untuk slot lain (misalnya, koordinat, poligon, dll ...). Sejauh kapan harus menggunakan [] atau $ ini masih tergantung pada jenis operasi. Tanda kurung "[]" dapat digunakan untuk memanggil nama dalam kerangka data tetapi terutama digunakan untuk pengindeksan sedangkan $ secara khusus digunakan untuk memanggil kolom dalam kerangka data. Alasan panggilan "tidak langsung" ke nama kolom berfungsi karena pengembang telah menambahkan fungsionalitas untuk memungkinkan pencarian rekursif melalui objek sp. Namun, untuk menghindari konflik nama (seperti dalam contoh Anda; memiliki kolom x, y dalam bingkai data Anda akan bertentangan dengan nama x, y dalam nama matriks @coord) ada beberapa konsistensi internal yang memeriksa alasan mengapa ini hanya berfungsi di beberapa contoh.

Salah satu karakteristik yang mudah digunakan adalah Anda dapat mengelompokkan objek spasial melalui indeks baris. Di sini saya mengatur ulang 10 objek pertama.

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

Atau, sebagai alternatif, sampel acak (n = 10) menggunakan vektor indeks baris.

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

Memahami pengindeksan dan cara menggunakan kurung adalah hal yang sangat penting dalam menulis kode R.

Sunting (03/24/2017): Harap dicatat bahwa kelas fitur sederhana (sf), mengikuti standar GeoJSON, kemungkinan akan menjadi standar baru untuk objek spasial di R. Anda dapat membaca deskripsi rinci tentang kelas ini di CRAN sf situs Wikipedia Fitur untuk R .

Jeffrey Evans
sumber
Terima kasih atas penjelasan terperinci tentang apa yang terjadi di balik layar. Tampaknya untuk SpatialPointsDataFrametidak hanya kolom @ data, tetapi juga kolom @coords dapat diambil dengan $operator tanpa perlu memanggil slot @coords. Jadi sdat@coords$eastingmemberikan hasil yang sama dengan sdat$easting.
jirikadlec2
Sepertinya Anda memanggil kolom dalam data <at>. Ini tidak sama dengan slot <at> coords. Anda akan melihat bahwa jika Anda memanggil colnames (sdat <at> coords), Anda akan mengembalikan nama kolom matriks: "coords.x1", "coords.x2". Tidak perlu memegang koordinat dalam bingkai data dan, karena diduplikasi, pinggang memori.
Jeffrey Evans
Tidak. Saya tidak memanggil kolom dalam data <at>. Menggunakan SpatialPointsDataFrame dari skrip sampel saya, colnames(locations@coords)mengembalikan [1] "x" "y"tetapi colnames(locations@data)mengembalikan [1] "v1" "v2". Mungkin perilaku ini tergantung pada fungsi apa yang digunakan untuk membuat SpatialPointsDataFrame?
jirikadlec2
Sebenarnya saya memiliki kesalahan dalam komentar pertama saya. sdat@coords$eastingtidak berfungsi karena sdat @ coords adalah sebuah matriks. Tetapi sdat@coords[,"easting"]setara dengan sdat@coords[,1]dan untuk sdat$easting.
jirikadlec2
Satu peringatan, colnames () digunakan untuk mengembalikan nama kolom dalam matriks sedangkan, names () akan mengembalikan NULL. Meskipun, baik nama () dan colnames () akan berfungsi pada objek dataframe seperti data <at>. Cara terbaik untuk mengambil data dari matriks coat <at> adalah dengan mengindeksnya: sdat <at> coords [, 1] atau dengan nama kolom sdat <at> coords [, "coords.x1"] tetapi seperti yang Anda catat $ lakukan tidak berfungsi karena itu adalah objek matriks.
Jeffrey Evans
4

Anda harus mencoba str(locations)menjelaskan ini.

misalnya, ini benar:

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

Dan ini property1 <- locations$v1berfungsi, karena mereferensikan data.frame di dalam lokasi, @ data

Guillermo Olmedo
sumber
str(locations)memberi saya beberapa petunjuk bagus. Sekarang saya mengerti bahwa @ini digunakan untuk "slot kelas". Tapi saya masih tidak mengerti mengapa property9 <- locations$xbekerja ketika names(locations)tidak mengandung kolom bernamax
jirikadlec2
1
Saat Anda membuat SpatialPointDataFrame, Anda menetapkan x dan y sebagai nama koordinat. Jika Anda melihat lokasi @ coords Anda dapat melihat matriks dengan koordinat. Juga, jika Anda mencoba membuat kolom baru di @ data dengan nama "x", Anda tidak bisa, karena sudah digunakan sebagai nama koordinat.
Guillermo Olmedo
Saya masih belum mendapatkan 'sihir' seperti apa yang SpatialPointsDataFramedigunakan objek untuk mengakses koordinat dengan $operator. Tapi setidaknya saya lebih nyaman menggunakannya sekarang. Saya menjalankan kode berikut: colnames(locations@coords) <- c("easting","northing") Setelah saya jalankan, locations$eastingberi saya vektor koordinat x dan locations$northingberi saya vektor koordinat y.
jirikadlec2
Saya pikir dalam beberapa hal R menganggap dua kolom untuk koordinat sebagai dua kolom lagi dari bagian dataframe dari SpatialPointsDataFrame. Itulah sebabnya Anda dapat memiliki kolom dengan nama yang sama di dalam slot @ data
Guillermo Olmedo
1
Tampaknya penamaan kolom dalam @coordsmatriks SpatialPointsDataFrametergantung pada bagaimana SpatialPointsDataFrameobjek itu dibuat. Metode satu: coordinates(sdat) <- x ~ yakan menamai ulang kolom untuk "coords.x1", "coords.x2". Metode dua: sdat <- SpatialPointsDataFrame(xy, attributes)akan mempertahankan nama kolom asli dari xymatriks.
jirikadlec2