Từ sự sp::over
giúp đỡ:
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.
Vì vậy, nếu bạn chuyển đổi của bạn SpatialPolygonsDataFrame
để SpatialPolygons
bạn lấy lại một vector của các chỉ mục và bạn có thể tập hợp con điểm của bạn về 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
>
Đối với những người nghi ngờ, đây là bằng chứng cho thấy chi phí chuyển đổi không phải là vấn đề:
Hai chức năng - đầu tiên là phương pháp của Jeffrey Evans, sau đó là bản gốc của tôi, sau đó là chuyển đổi bị hack của tôi, sau đó là phiên bản dựa trên gIntersects
câu trả lời của 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,]
}
Bây giờ là một ví dụ trong thế giới thực, tôi đã phân tán một số điểm ngẫu nhiên trên tập columbus
dữ liệu:
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
Có vẻ tốt
plot(columbus)
points(pts)
Kiểm tra các chức năng đang làm điều tương tự:
> identical(evans(pts,columbus),rowlings(pts,columbus))
[1] TRUE
Và chạy 500 lần cho điểm chuẩ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
Theo trực giác của tôi, nó không phải là một chi phí lớn, trên thực tế, nó có thể ít chi phí hơn là chuyển đổi tất cả các chỉ mục hàng thành ký tự và trở lại hoặc chạy na.omit để nhận các giá trị bị thiếu. Điều này tình cờ dẫn đến một chế độ thất bại khác của evans
chức năng ...
Nếu một hàng của khung dữ liệu đa giác là tất cả NA
(hoàn toàn hợp lệ), thì lớp phủ với SpatialPolygonsDataFrame
các điểm trong đa giác đó sẽ tạo ra một khung dữ liệu đầu ra với tất cả NA
s, evans()
sau đó sẽ giảm:
> 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
>
NHƯNG gIntersects
nhanh hơn, ngay cả khi phải quét ma trận để kiểm tra các giao điểm trong R thay vì trong mã C. Tôi nghi ngờ các prepared geometry
kỹ năng của GEOS, tạo ra các chỉ mục không gian - vâng, với prepared=FALSE
thời gian lâu hơn một chút, khoảng 5,5 giây.
Tôi ngạc nhiên không có chức năng nào trả thẳng các chỉ số hoặc điểm. Khi tôi viết splancs
cách đây 20 năm, các hàm đa giác có cả ...