เข้าร่วมข้อมูลจุดเชิงพื้นที่กับรูปหลายเหลี่ยมใน R


21

ฉันพยายามทำการรวมเชิงพื้นที่ระหว่างข้อมูลจุดและข้อมูลรูปหลายเหลี่ยม

ฉันมีข้อมูลที่ระบุพิกัดเชิงพื้นที่ของเหตุการณ์ในไฟล์ csv ของฉัน A และมีไฟล์อีกไฟล์หนึ่งคือ shapefile B ซึ่งมีขอบเขตของพื้นที่เป็นรูปหลายเหลี่ยม

head(A)
  month   longitude latitude lsoa_code                   crime_type
1 2014-09 -1.550626 53.59740 E01007359        Anti-social behaviour
2 2014-09 -1.550626 53.59740 E01007359                 Public order
3 2014-09 -1.865236 53.93678 E01010646        Anti-social behaviour

head(B@data)
  code      name                                  altname
0 E05004934 Longfield, New Barn and Southfleet    <NA>
1 E05000448                   Lewisham Central    <NA>
2 E05003149                            Hawcoat    <NA>

ฉันต้องการเข้าร่วมกับข้อมูลอาชญากรรม A กับ shapefile ของฉันเพื่อทำแผนที่เหตุการณ์อาชญากรรมที่เกิดขึ้นในพื้นที่ของฉัน A. น่าเสียดายที่ฉันไม่สามารถทำการเข้าร่วมคุณลักษณะตามcodeรหัสใน A หมายถึงหน่วยต่าง ๆ กว่ารหัสใน B

ฉันอ่านบทช่วยสอนและโพสต์จำนวนหนึ่งแล้ว แต่ไม่พบคำตอบ ฉันเหนื่อย:

joined = over(A, B)

และoverlayแต่ไม่บรรลุสิ่งที่ฉันต้องการ

มีวิธีในการเข้าร่วมนี้โดยตรงหรือต้องการการเปลี่ยนรูปแบบกลางจาก A ไปเป็นรูปแบบอื่นหรือไม่?

แนวคิดฉันต้องการเลือกจุดเหล่านั้นของ A ที่อยู่ในcodeพื้นที่ของ B (คล้ายกับ "เข้าร่วมตามตำแหน่งเชิงพื้นที่ใน ArcGIS")

มีใครมีปัญหานี้และแก้ไขได้ไหม


คุณดูpoint.in.polygon()ในแพ็คเกจspหรือไม่

@ arvi1000 ฉันมีและจะลองอีกครั้ง ความคิดของผมเกี่ยวกับการpoint.in.polygonเป็นว่าเรื่องนี้จะเก็บรักษาตัวแปรและmonth crime_typeคุณรู้เรื่องนั้นไหม
ben_aaron

ฉันลองอีกเล็กน้อยpoint.in.polyและในที่สุดก็เลือกประเด็นเหล่านั้นที่ตกอยู่ในรูปหลายเหลี่ยมที่เกี่ยวข้อง ขอบคุณ
ben_aaron

จากนั้นบางทีคุณควรตอบคำถามด้วยคำตอบของคุณเอง จำไว้ว่าคำตอบที่ดีคือสิ่งที่เว็บไซต์นี้มีเกี่ยวกับ
SlowLearner

คำตอบ:


8

ฟังก์ชัน point.in.poly ในแพ็คเกจ spatialEco ส่งคืนวัตถุ SpatialPointsDataFrame ของจุดที่ตัดกับวัตถุรูปหลายเหลี่ยม sp และเลือกเพิ่มแอตทริบิวต์รูปหลายเหลี่ยม

ก่อนอื่นให้เพิ่มแพ็คเกจที่ต้องการและสร้างข้อมูลตัวอย่าง

require(spatialEco)
require(sp)
data(meuse)
coordinates(meuse) = ~x+y
sr1=Polygons(list(Polygon(cbind(c(180114, 180553, 181127, 181477, 181294, 181007, 180409,
  180162, 180114), c(332349, 332057, 332342, 333250, 333558, 333676,
  332618, 332413, 332349)))),'1')
sr2=Polygons(list(Polygon(cbind(c(180042, 180545, 180553, 180314, 179955, 179142, 179437,
  179524, 179979, 180042), c(332373, 332026, 331426, 330889, 330683,
  331133, 331623, 332152, 332357, 332373)))),'2')
sr3=Polygons(list(Polygon(cbind(c(179110, 179907, 180433, 180712, 180752, 180329, 179875,
  179668, 179572, 179269, 178879, 178600, 178544, 179046, 179110),
  c(331086, 330620, 330494, 330265, 330075, 330233, 330336, 330004,
  329783, 329665, 329720, 329933, 330478, 331062, 331086)))),'3')
sr4=Polygons(list(Polygon(cbind(c(180304, 180403,179632,179420,180304),
  c(332791, 333204, 333635, 333058, 332791)))),'4')
sr=SpatialPolygons(list(sr1,sr2,sr3,sr4))
srdf=SpatialPolygonsDataFrame(sr, data.frame(row.names=c('1','2','3','4'), PIDS=1:4, y=runif(4)))

ทีนี้มาดูข้อมูลและพล็อตมันอย่างรวดเร็ว

head(srdf@data)  # polygons
head(meuse@data) # points
plot(srdf)
points(meuse, pch=20)

สุดท้ายเราสามารถตัดกันจุดด้วยรูปหลายเหลี่ยม ผลลัพธ์จะเป็นวัตถุ SpatialPointsDataFrame ด้วยในกรณีนี้แอตทริบิวต์พิเศษสองรายการ (PIDS, y) ที่มีอยู่ในข้อมูลรูปหลายเหลี่ยม srdf

  pts.poly <- point.in.poly(meuse, srdf)
    head(pts.poly@data)

หากไม่มีคอลัมน์ระบุตัวตนที่ไม่ซ้ำกันในข้อมูลรูปหลายเหลี่ยมคุณสามารถเพิ่มได้อย่างง่ายดาย

srdf@data$poly.ids <- 1:nrow(srdf) 

เมื่อเรามีจุดและรูปหลายเหลี่ยมตัดกันเราสามารถรวมคะแนนโดยใช้รูปหลายเหลี่ยม ID ที่ไม่ซ้ำซึ่งเป็นคุณลักษณะในข้อมูลรูปหลายเหลี่ยม

# Number of points in each polygon
tapply(pts.poly@data$lead, pts.poly@data$PIDS, FUN=length)

# Mean lead in each polygon
tapply(pts.poly@data$lead, pts.poly@data$PIDS, FUN=mean)

@ arvi1000 ใช่ แต่ sp :: point.in.polygon สร้างตรรกะ spatialEco: point.in.poly เป็น wrapper นานกว่า แต่ส่งคืน sp SpatialPointsDataFrame และทางลัดบางขั้นตอนที่เกี่ยวข้องกับแอตทริบิวต์รูปหลายเหลี่ยมคล้ายกับ raster: intersect ทำให้ rgeos :: gIntersect
Jeffrey Evans

sp::point.in.polygonจริง ๆ แล้วคืนค่าตัวเลข (0 = จุดอยู่นอก, 1 = ข้างใน, 2 = บนขอบ, 3 = บนจุดยอด) อาจเป็นสิ่งที่ถูกต้องในบางสถานการณ์ คิดว่ามันเป็นประโยชน์ที่จะต้องทราบที่นี่เนื่องจากนี่เป็นผล google อันดับต้น ๆ สำหรับคำที่เกี่ยวข้อง
arvi1000

27

over()จากแพ็คเกจspอาจสับสนเล็กน้อย แต่ใช้งานได้ดี ฉันสมมติว่าคุณได้สร้าง "A" spatial ด้วยcoordinates(A) <- ~longitude+latitude:

# Overlay points and extract just the code column: 
a.data <- over(A, B[,"code"])

แทนที่จะเป็นวัตถุเชิงพื้นที่จุดนี่จะให้กรอบข้อมูลกับคุณโดยไม่มีหมายเลขเดียวกัน แถวเป็น A และ "รหัส" ตัวแปรเดียวจากรูปหลายเหลี่ยมที่ตัดกันจาก B

# Add that data back to A:
A$bcode <- a.data$code

ฉันพบว่าover()มีปัญหาเกี่ยวกับจุดที่จุดยอดของรูปหลายเหลี่ยมแม้ว่าฉันคิดว่านี่เป็นวิธีที่ง่ายที่สุดที่ฉันพบ
JMT2080AD

คุณมีปัญหาอะไรบ้าง?
Simbamangu

ยกเว้น. ฉันต้องสำรวจมันต่อไป ฉันจะส่งข้อมูลบางอย่างให้คุณในภายหลังวันนี้และเราสามารถดูกันถ้าคุณสนใจ ฉันอาจจะผิด แต่ฉันค่อนข้างมั่นใจว่ามีความเสื่อมในอัลกอริทึมที่ต้องได้รับการดูแลอย่างน้อยสำหรับข้อมูลของฉัน
JMT2080AD

ไม่เป็นไร. มันจะต้องมีบางอย่างกับข้อมูลของฉัน ชุดทดลองนี้ทำงานได้ดี r-fiddle.org/#/fiddle?id=m5sTjE4N&version=1
JMT2080AD

1
นี่เป็นวิธีที่ตรงไปตรงมามากกว่าคำตอบที่ได้รับการยอมรับและไม่จำเป็นต้องติดตั้งแพคเกจเพิ่มเติมนอกเหนือจาก rgdal
ไบรซ์แฟรงก์

0

นี่เป็นวิธี dplyr like:

library(spdplyr)

ukcounties <- geojsonio::geojson_read("data/Westminster_Parliamentary_Constituencies_December_2018_UK_BGC/uk_country.geojson",
                                      what = "sp")
pop <- read_excel("data/SAPE20DT7-mid-2017-parlicon-syoa-estimates-unformatted.xls",sheet = "data")
pop <- janitor::clean_names(pop)

ukcounties_pop <- ukcounties %>% inner_join(pop, by = c("pcon18nm" = "pcon11nm"))

ข้อมูลประชากรมาจาก: https://www.ons.gov.uk/peoplepopulationandcommunity/populationandmigration/populationestimates/datasets/parliamentaryconstituencymidyearpulation

ฉันต้องแปลงไฟล์รูปร่างที่ดาวน์โหลดจากเป็น geoJson: https://geoportal.statistics.gov.uk/datasets/westminster-parliamentary-constituencies-december-2018-uk-bgc/data?page=1

คุณสามารถทำได้โดย:

uk_constituencies <- readOGR("data/Westminster_Parliamentary_Constituencies_December_2018_UK_BGC/Westminster_Parliamentary_Constituencies_December_2018_UK_BGC.shp")
uk_constituencies # this is in tmerc format. we need to convert it to WGS84 required by geoJson format.

# First Convert to Longitude / Latitude with WGS84 Coordinate System
wgs84 = '+proj=longlat +datum=WGS84'
uk_constituencies_trans <- spTransform(uk_constituencies, CRS(wgs84))

# Convert from Spatial Dataframe to GeoJSON
uk_constituencies_json <- geojson_json(uk_constituencies_trans)

# Save as GeoJSON file on the file system.
geojson_write(uk_constituencies_json, file = "data/Westminster_Parliamentary_Constituencies_December_2018_UK_BGC/uk_country.geojson")

#read back in:
ukcounties <- geojsonio::geojson_read("data/Westminster_Parliamentary_Constituencies_December_2018_UK_BGC/uk_country.geojson",
                                      what = "sp")
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.