จากความ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
>
สำหรับผู้สงสัยสองคนนี่คือหลักฐานว่าค่าใช้จ่ายในการแปลงไม่ใช่ปัญหา:
สองฟังก์ชั่น - วิธีแรกของเจฟฟรีย์อีแวนส์จากนั้นเป็นต้นฉบับของฉันจากนั้นเปลี่ยนการแฮ็กของฉันจากนั้นเป็นเวอร์ชันที่อิง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
เร็วกว่าแม้ว่าจะต้องกวาดเมทริกซ์เพื่อตรวจสอบจุดตัดใน R แทนที่จะเป็นรหัส C ฉันสงสัยว่ามันเป็นprepared geometry
ทักษะของ GEOS สร้างดัชนีเชิงพื้นที่ - ใช่ด้วยprepared=FALSE
ความยาวประมาณ 5.5 วินาที
ฉันประหลาดใจที่ไม่มีฟังก์ชั่นที่จะคืนดัชนีหรือคะแนนโดยตรง เมื่อฉันเขียนsplancs
20 ปีที่ผ่านมาฟังก์ชั่นจุดในรูปหลายเหลี่ยมมีทั้ง ...