การเข้าร่วมรูปหลายเหลี่ยมใน R


29

ฉันสงสัยว่าจะเข้าร่วมรูปหลายเหลี่ยมเชิงพื้นที่โดยใช้รหัส R ได้อย่างไร

ฉันทำงานกับข้อมูลสำมะโนประชากรที่บางพื้นที่เปลี่ยนแปลงตลอดเวลาและฉันต้องการเข้าร่วมรูปหลายเหลี่ยมและข้อมูลที่เกี่ยวข้องและเพียงรายงานเกี่ยวกับพื้นที่ที่เข้าร่วม ฉันกำลังรักษารายการรูปหลายเหลี่ยมที่มีการเปลี่ยนแปลงสำมะโนประชากรเป็นสำมะโนประชากรและฉันวางแผนที่จะรวม ฉันต้องการใช้รายชื่อพื้นที่นี้เป็นรายการค้นหาเพื่อใช้กับข้อมูลการสำรวจสำมะโนประชากรจากหลายปี

ฉันสงสัยว่าฟังก์ชัน R ใดที่จะใช้เพื่อผสานรูปหลายเหลี่ยมที่เลือกไว้และข้อมูลที่เกี่ยวข้อง ฉันได้ทำมัน แต่ก็สับสนกับผลลัพธ์


คำตอบสำหรับการดำเนินการทางเรขาคณิตส่วนใหญ่เช่นการยุบหลายเหลี่ยม, ซ้อนทับ, จุดในรูปหลายเหลี่ยม, แยก, สหภาพ ฯลฯ ฯลฯ เป็นแพคเกจ rgeos
Spacedman

1
สำนักสำรวจสำมะโนประชากรของสหรัฐตีพิมพ์ตารางเพื่อทำสิ่งนี้ในปี 1990-2000 และ 2000-2010 พวกเขาสามารถจัดการกับฐานข้อมูลร่วมซึ่งจะดำเนินการโดยR's mergeฟังก์ชั่น
whuber

คำตอบ:


39

วิธีการแก้ปัญหาต่อไปนี้จะขึ้นอยู่กับการโพสต์โดยโรเจอร์ Bivand บนR-sig-Geo ฉันเอาตัวอย่างของเขามาแทนที่เชพไฟล์เยอรมันด้วยข้อมูลสำมะโนประชากรจากโอเรกอนที่คุณสามารถดาวน์โหลดได้จากที่นี่ (นำส่วนประกอบเชพไฟล์ทั้งหมดมาจาก

เริ่มต้นด้วยการโหลดแพ็คเกจที่จำเป็นและนำเข้ารูปร่างไฟล์ลงใน R

# Required packages
libs <- c("rgdal", "maptools", "gridExtra")
lapply(libs, require, character.only = TRUE)

# Import Oregon census data
oregon <- readOGR(dsn = "path/to/data", layer = "orcounty")
oregon.coords <- coordinates(oregon)

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

# Generate IDs for grouping
oregon.id <- cut(oregon.coords[,1], quantile(oregon.coords[,1]), include.lowest=TRUE)

# Merge polygons by ID
oregon.union <- unionSpatialPolygons(oregon, oregon.id)

# Plotting
plot(oregon)
plot(oregon.union, add = TRUE, border = "red", lwd = 2)

แฟ้มรูปร่างโอเรกอนดั้งเดิมและจัดกลุ่ม

จนถึงตอนนี้ดีมาก อย่างไรก็ตามข้อมูลคุณลักษณะที่เกี่ยวข้องกับภูมิภาคย่อย shapefile เดิม (เช่นความหนาแน่นของประชากรในพื้นที่อื่น ๆ ) unionSpatialPolygonsจะหายไปเมื่อการดำเนินการ ฉันเดาว่าคุณต้องการรวมข้อมูลการสำรวจสำมะโนประชากรของคุณที่เกี่ยวข้องกับ Shapefile เช่นกันดังนั้นคุณจะต้องมีขั้นตอนกลาง

ก่อนอื่นคุณต้องแปลงรูปหลายเหลี่ยมของคุณเป็น dataframe เพื่อทำการรวม ตอนนี้ขอใช้คอลัมน์แอตทริบิวต์ข้อมูลที่หกถึงแปด ( "AREA", "POP1990", "POP1997") sumและรวมพวกเขาตามรหัสข้างต้นการใช้ฟังก์ชั่น

# Convert SpatialPolygons to data frame
oregon.df <- as(oregon, "data.frame")

# Aggregate and sum desired data attributes by ID list
oregon.df.agg <- aggregate(oregon.df[, 6:8], list(oregon.id), sum)
row.names(oregon.df.agg) <- as.character(oregon.df.agg$Group.1)

สุดท้ายให้คืนค่า dataframe ของคุณกลับไปเป็นSpatialPolygonsDataFrameการนำเสนอรูปร่างไฟล์ที่รวมเป็นหนึ่งเดียวก่อนหน้านี้oregon.unionและคุณจะได้รับทั้งรูปหลายเหลี่ยมแบบทั่วไปและข้อมูลการสำรวจสำมะโนประชากรของคุณซึ่งได้มาจากขั้นตอนการสรุปรวมด้านบน

# Reconvert data frame to SpatialPolygons
oregon.shp.agg <- SpatialPolygonsDataFrame(oregon.union, oregon.df.agg)

# Plotting
grid.arrange(spplot(oregon, "AREA", main = "Oregon: original county area"), 
             spplot(oregon.shp.agg, "AREA", main = "Oregon: aggregated county area"), ncol = 1)

พื้นที่โอเรกอน


10

นี่คือวิธีการแก้ปัญหาโดยใช้แพคเกจเอสเอฟ:

library(tidycensus)
library(dplyr)
library(sf)
library(ggplot2)

# get data from tindycensus for demonstration (note you need an API key, folow instructions here: https://walkerke.github.io/tidycensus/articles/basic-usage.html)
census <- tidycensus::get_acs(geography = "tract", variables = "B19013_001",
                           state = "TX", county = "Tarrant", geometry = TRUE) %>% 
  arrange(NAME)

# reduce dataset size
census <- census[1:8,]

# create grouping variable
group_1 <- census$GEOID[1:2]
group_2 <- census$GEOID[6:8]

census <- census %>% mutate(group = case_when(GEOID %in% group_1 ~ 'newgroup1',
                                              GEOID %in% group_2 ~ 'newgroup2',
                                              TRUE ~ GEOID))

# summarise by grouping variable (performs a union on grouped polygons and sums 'estimate')
census2 <- group_by(census, group) %>% 
  summarise(estimate = sum(estimate), do_union = TRUE)

# visualise using ggplot2 development version and facet by merged/unmerged datasets
plot_data <- rbind(census %>% select(group, estimate) %>%
                     mutate(facet = "unmerged"), 
                   census2 %>% mutate(facet = "merged"))

gp <- ggplot() + 
      geom_sf(data = plot_data, aes(fill = estimate), color = 'white') + 
      scale_fill_viridis_c() + 
      facet_wrap(~facet, ncol = 1)

ป้อนคำอธิบายรูปภาพที่นี่


ฉันคิดว่าฉันแค่เพิ่มการเตือนเล็กน้อยที่นี่ในกรณี: ระวังการใช้summarise()อนุพันธ์กับdo_unionอาร์กิวเมนต์เนื่องจากฉันเพิ่งทำอะไรบางอย่างsummarise_if(shapefile, predic.function, sum, na.rm = TRUE, do_union = TRUE)ซึ่งจบลงด้วยการรวม TRUE ในแต่ละเซลล์ (เช่น +1 สำหรับการดำเนินการทั้งหมด) ต้องการตรวจสอบเพิ่มเติมเพื่อหาว่าเป็นสิ่งที่ควรรายงาน (อย่างน้อยสำหรับการเตือนเพิ่มเติม) ... ?
stragu
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.