Saya punya SpatialPointsDataFrame
dengan beberapa data tambahan. Saya ingin mengekstrak titik-titik itu di dalam poligon dan pada saat yang sama, menyimpan SPDF
objek dan data terkait.
Sejauh ini saya kurang beruntung dan terpaksa melakukan pencocokan dan penggabungan melalui ID umum, tetapi ini hanya berfungsi karena saya memiliki data grid dengan masing-masing IDS.
Ini contoh cepat, saya mencari poin di dalam kotak merah.
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")
Pendekatan yang paling jelas adalah menggunakan over
, tetapi ini mengembalikan data dari poligon.
> over(pts, ply)
polyvar
1 NA
2 357
3 357
4 NA
5 357
6 357
Jawaban:
Dari
sp::over
bantuan:Jadi, jika Anda mengonversi
SpatialPolygonsDataFrame
keSpatialPolygons
Anda mendapatkan kembali vektor indeks dan Anda dapat mengelompokkan poin Anda padaNA
:Bagi yang ragu, inilah bukti bahwa overhead konversi bukan masalah:
Dua fungsi - metode pertama Jeffrey Evans, lalu yang asli, lalu konversi yang diretas, kemudian versi berdasarkan
gIntersects
jawaban Josh O'Brien:Sekarang untuk contoh dunia nyata, saya telah menyebarkan beberapa poin acak ke
columbus
set data:Kelihatan bagus
Periksa fungsi melakukan hal yang sama:
Dan jalankan 500 kali untuk pembandingan:
Sesuai intuisi saya, ini bukan overhead yang bagus, sebenarnya mungkin lebih sedikit overhead daripada mengubah semua indeks baris menjadi karakter dan kembali, atau menjalankan na.omit untuk mendapatkan nilai yang hilang. Yang kebetulan mengarah ke mode kegagalan
evans
fungsi lainnya ...Jika satu baris bingkai data poligon adalah semua
NA
(yang benar-benar valid), maka hamparan denganSpatialPolygonsDataFrame
untuk titik-titik dalam poligon tersebut akan menghasilkan bingkai data keluaran dengan semuaNA
s, yangevans()
kemudian akan turun:TAPI
gIntersects
lebih cepat, bahkan dengan harus menyapu matriks untuk memeriksa persimpangan di R daripada dalam kode C. Saya menduga ini adalahprepared geometry
keterampilan GEOS, membuat indeks spasial - ya, denganprepared=FALSE
itu membutuhkan waktu sedikit lebih lama, sekitar 5,5 detik.Saya terkejut tidak ada fungsi untuk langsung mengembalikan indeks atau poin. Ketika saya menulis
splancs
20 tahun yang lalu fungsi point-in-polygon memiliki keduanya ...sumber
sp
menyediakan formulir yang lebih pendek untuk memilih fitur berdasarkan persimpangan spasial, mengikuti contoh OP:pada:
Di balik layar ini adalah kependekan dari
Yang perlu diperhatikan adalah bahwa ada
geometry
metode yang menjatuhkan atribut:over
mengubah perilaku jika argumen keduanya memiliki atribut atau tidak (ini adalah kebingungan OP). Ini berfungsi di semua kelas Spasial *sp
, meskipun beberapaover
metode memerlukanrgeos
, lihat sketsa ini untuk detail, misalnya kasus beberapa kecocokan untuk poligon yang tumpang tindih.sumber
Anda berada di jalur yang benar dengan berakhir. Rownames dari objek yang dikembalikan sesuai dengan indeks baris poin. Anda dapat menerapkan pendekatan tepat Anda hanya dengan beberapa baris kode tambahan.
sumber
Apakah ini yang Anda cari?
Satu catatan, saat diedit: Panggilan pembungkus ke
apply()
diperlukan untuk membuat pekerjaan ini denganSpatialPolygons
objek sewenang-wenang , mungkin berisi lebih dari satu fitur poligon. Terima kasih kepada @Spacedman karena mendorong saya untuk mendemonstrasikan bagaimana menerapkan ini pada kasus yang lebih umum.sumber
ply
memiliki lebih dari satu fitur, karenagIntersects
mengembalikan matriks dengan satu baris untuk setiap fitur. Anda mungkin dapat menyapu baris untuk nilai yang BENAR.apply(gIntersects(pts, ply, byid=TRUE), 2, any)
. Bahkan, saya akan melanjutkan dan beralih jawaban untuk itu, karena mencakup kasus satu poligon juga.any
. Itu mungkin sedikit lebih cepat daripada versi yang baru saya benchmark.obrien
danrowlings2
menjalankan leher dan leher, denganobrien
mungkin 2% lebih cepat.pp
harus memilikiID
yang menunjukkan di mana poligon titik berada.Berikut ini pendekatan yang mungkin menggunakan
rgeos
paket. Pada dasarnya, ini menggunakangIntersection
fungsi yang memungkinkan Anda untuk memotong duasp
objek. Dengan mengekstraksi ID dari titik-titik yang terletak di dalam poligon, Anda kemudian dapat mengelompokkan bagian asli AndaSpatialPointsDataFrame
, menyimpan semua data yang sesuai. Kode ini hampir menjelaskan sendiri, tetapi jika ada pertanyaan, jangan ragu untuk bertanya!sumber
tmp
menjadipts.intersect
? Juga, mem-parsing nama-nama yang dikembalikan seperti itu tergantung pada perilaku tidak berdokumen.tmp
, lupa untuk menghapusnya saat menyelesaikan kode. Juga, Anda benar tentang penguraiandimnames
. Ini semacam solusi cepat untuk memberikan jawaban cepat kepada penanya, dan tentu saja ada pendekatan yang lebih baik (dan lebih universal), misalnya milik Anda :-)Ada solusi yang sangat sederhana menggunakan
spatialEco
perpustakaan.Periksa hasilnya:
sumber