在R中连接多边形


29

我想知道如何使用R代码连接空间多边形?

我正在处理某些区域随时间变化的人口普查数据,我希望将多边形和相应的数据合并在一起,并仅报告合并区域。我正在维护一个具有随人口普查而变化的多边形列表,并计划合并。我想将此区域名称列表用作查找列表,以应用于不同年份的人口普查数据。

我想知道使用什么R函数来合并选定的多边形和相应的数据。我已经用谷歌搜索过,但是结果简直让我感到困惑。


rgeos软件包是大多数几何操作(如多边形溶解,覆盖,多边形点,交点,并集等)的答案。
Spacedman

1
美国人口普查局为此发布了表格,用于1990-2000年和2000-2010年。可以使用数据库连接来管理它们,这些连接由Rmerge功能实现。
ub

Answers:


39

以下解决方案基于Roger Bivand在R-sig-Geo上的帖子。我以他的示例为例,将俄勒冈州的一些人口普查数据替换为德国的shapefile,您可以从此处下载(从“俄勒冈州的县和人口普查数据”中获取所有shapefile组件)。

让我们从加载所需的程序包并将shapefile导入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

到目前为止,一切都很好。但是,执行时会丢失与原始shapefile的子区域有关的数据属性(例如,人口密度,面积等)unionSpatialPolygons。我猜您也想汇总与shapefile相关联的普查数据,因此您需要一个中间步骤。

首先,必须将多边形转换为数据框才能执行聚合。现在,使数据属性列为第六到第八列(“ AREA”,“ POP1990”,“ POP1997”),并根据上述ID应用功能对它们进行汇总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)

最后,将您的数据框重新转换为SpatialPolygonsDataFrame提供以前统一的shapefile,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

这是使用sf软件包的解决方案:

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.