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 SpatialPolygonsDataFramehiç SpatialPolygonssizin 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 gIntersectsJosh 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, columbusveri 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 evansfonksiyonun 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 NAbu 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 geometryGEOS'un yeteneklerinden, uzaysal dizinler oluşturduğundan şüpheleniyorum - evet, prepared=FALSEbiraz 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. splancs20 yıl önce yazdığımda , çokgen noktası fonksiyonlarının her ikisi de ...