로부터 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.
당신이 당신의 변환 그래서 만약 SpatialPolygonsDataFrame
에 SpatialPolygons
당신이 인덱스의 벡터를 다시 얻을 당신은 당신의 포인트를 서브 세트 수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
>
의심스러운 사람들에게는 변환 오버 헤드가 문제가되지 않는다는 증거가 있습니다.
두 가지 기능-먼저 Jeffrey Evans의 방법, 내 원본, 해킹 된 변환, gIntersects
Josh O'Brien의 답변 을 기반으로 한 버전 :
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,]
}
실제 예제에서는 columbus
데이터 세트에 임의의 점을 뿌렸습니다 .
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
좋아 보인다
plot(columbus)
points(pts)
기능이 같은 일을하고 있는지 확인하십시오.
> identical(evans(pts,columbus),rowlings(pts,columbus))
[1] TRUE
벤치마킹을 위해 500 회 실행 :
> 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
내 직감에 따르면, 큰 오버 헤드는 아니지만 실제로 모든 행 인덱스를 문자로 변환하고 다시 반환하거나 na.omit을 실행하여 누락 된 값을 얻는 것보다 오버 헤드가 적을 수 있습니다. 실수로evans
기능 ...
폴리곤 데이터 프레임의 행이 모두 NA
(완전히 유효한) 경우 SpatialPolygonsDataFrame
해당 폴리곤의 점에 대한 오버레이 는 모든 NA
s가 있는 출력 데이터 프레임을 생성하여 evans()
드롭됩니다.
> 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
>
그러나 gIntersects
C 코드가 아닌 R의 교차점을 검사하기 위해 매트릭스를 스위프해야하더라도 더 빠릅니다. 나는 그것의 의심prepared geometry
공간 인덱스를 생성하는 GEOS 기술을 예 prepared=FALSE
, 약 5.5 초가 조금 더 걸립니다.
지수 나 포인트를 직선으로 돌려주는 함수가 없다는 것에 놀랐습니다. 내가 splancs
20 년 전에 쓰면서 다각형 함수는 둘 다 가지고있었습니다.