Yardımdan sp::over
:
x = "SpatialPoints", y = "SpatialPolygons" returns a numeric
vector of length equal to the number of points; the number is
the index (number) of the polygon of ‘y’ in which a point
falls; NA denotes the point does not fall in a polygon; if a
point falls in multiple polygons, the last polygon is
recorded.
İstemiyorsun, mutfakta annene dönüştürmek Yani eğer SpatialPolygonsDataFrame
hiç SpatialPolygons
sizin indeksler bir vektör geri almak ve üzerinde puan subsetine edebilirsiniz NA
:
> over(pts,as(ply,"SpatialPolygons"))
[1] NA 1 1 NA 1 1 NA NA 1 1 1 NA NA 1 1 1 1 1 NA NA NA 1 NA 1 NA
[26] 1 1 1 NA NA NA NA NA 1 1 NA NA NA 1 1 1 NA 1 1 1 NA NA NA 1 1
[51] 1 NA NA NA 1 NA 1 NA 1 NA NA 1 NA 1 1 NA 1 1 NA 1 NA 1 1 1 1
[76] 1 1 1 1 1 NA NA NA 1 NA 1 NA NA NA NA 1 1 NA 1 NA NA 1 1 1 NA
> nrow(pts)
[1] 100
> pts = pts[!is.na(over(pts,as(ply,"SpatialPolygons"))),]
> nrow(pts)
[1] 54
> head(pts@data)
var1 var2
2 0.04001092 v
3 0.58108350 v
5 0.85682609 q
6 0.13683264 y
9 0.13968804 m
10 0.97144627 o
>
Şüpheliler için, dönüşüm yükünün bir sorun olmadığını gösteren kanıtlar:
İki işlev - önce Jeffrey Evans'ın yöntemi, sonra orijinalim, sonra saldırıya uğramış dönüşümüm, ardından gIntersects
Josh O'Brien'ın cevabına dayanan bir sürüm :
evans <- function(pts,ply){
prid <- over(pts,ply)
ptid <- na.omit(prid)
pt.poly <- pts[as.numeric(as.character(row.names(ptid))),]
return(pt.poly)
}
rowlings <- function(pts,ply){
return(pts[!is.na(over(pts,as(ply,"SpatialPolygons"))),])
}
rowlings2 <- function(pts,ply){
class(ply) <- "SpatialPolygons"
return(pts[!is.na(over(pts,ply)),])
}
obrien <- function(pts,ply){
pts[apply(gIntersects(columbus,pts,byid=TRUE),1,sum)==1,]
}
Şimdi gerçek dünya örneği için, columbus
veri kümesine bazı rastgele noktalar dağıttım :
require(spdep)
example(columbus)
pts=data.frame(
x=runif(100,5,12),
y=runif(100,10,15),
z=sample(letters,100,TRUE))
coordinates(pts)=~x+y
İyi görünüyor
plot(columbus)
points(pts)
İşlevlerin aynı şeyi yaptığını kontrol edin:
> identical(evans(pts,columbus),rowlings(pts,columbus))
[1] TRUE
Kıyaslama için 500 kez çalıştırın:
> system.time({for(i in 1:500){evans(pts,columbus)}})
user system elapsed
7.661 0.600 8.474
> system.time({for(i in 1:500){rowlings(pts,columbus)}})
user system elapsed
6.528 0.284 6.933
> system.time({for(i in 1:500){rowlings2(pts,columbus)}})
user system elapsed
5.952 0.600 7.222
> system.time({for(i in 1:500){obrien(pts,columbus)}})
user system elapsed
4.752 0.004 4.781
Benim sezgiye göre, bu büyük bir yük değil, aslında tüm satır dizinleri karakter ve geri dönüştürmek ya da eksik değerleri almak için na.omit çalıştırmak daha az bir ek yük olabilir. Bu arada evans
fonksiyonun başka bir arıza moduna yol açar ...
Çokgenler veri çerçevesinin bir satırı hepsi ise NA
(ki bu tamamen geçerlidir), o zaman SpatialPolygonsDataFrame
çokgendeki noktalara yönelik bindirme, tüm s'lerle birlikte bir çıkış veri çerçevesi oluşturur ve NA
bu evans()
da aşağıdakileri düşürür:
> columbus@data[1,]=rep(NA,20)
> columbus@data[5,]=rep(NA,20)
> columbus@data[17,]=rep(NA,20)
> columbus@data[15,]=rep(NA,20)
> set.seed(123)
> pts=data.frame(x=runif(100,5,12),y=runif(100,10,15),z=sample(letters,100,TRUE))
> coordinates(pts)=~x+y
> identical(evans(pts,columbus),rowlings(pts,columbus))
[1] FALSE
> dim(evans(pts,columbus))
[1] 27 1
> dim(rowlings(pts,columbus))
[1] 28 1
>
ANC gIntersects
, C kodundan ziyade R'deki kavşakları kontrol etmek için matrisi süpürmek zorunda kalsa bile daha hızlıdır. prepared geometry
GEOS'un yeteneklerinden, uzaysal dizinler oluşturduğundan şüpheleniyorum - evet, prepared=FALSE
biraz daha uzun sürüyor, yaklaşık 5.5 saniye.
Endeksleri veya puanları doğrudan geri döndürmek için bir fonksiyon olmadığına şaşırdım. splancs
20 yıl önce yazdığımda , çokgen noktası fonksiyonlarının her ikisi de ...