将全部或部分多边形保留在较大的多边形中,且不带负缓冲区

时间:2020-06-30 22:48:40

标签: r sf

我想保留人口普查地理范围较大的人口普查区域。这些区域应完全适合较大的地理区域。

我可以使用负缓冲区来执行此操作,但是有更好的方法吗?

library(tidyverse)
library(sf)
library(tidycensus)
library(tigris)
library(tmap)

balt <- places("Maryland",
               year = 2018,
               class = "sf") %>% 
  filter(NAME == "Baltimore") %>% 
  st_transform(4326)

balt_tracts <- get_acs(geography = "tract",
                       variables = "B01003_001E", # population
                       year = 2018,
                       state = "Maryland",
                       survey = "acs5",
                       geometry = TRUE) %>% 
  st_transform(4326)

balt_tracts %>% 
  .[st_within(st_buffer(., -0.001),  
              balt) %>% lengths > 0,] %>% 
  qtm()

enter image description here

相交处会在较大地理区域之外返回具有共同边缘的区域,这是我不希望的。

balt_tracts[balt,] %>% 
  qtm()

enter image description here

修改

我正在寻找一种方法来获取st_overlaps()的结果,并仅保留边界(balt)内的那些多边形。

balt_tracts[st_overlaps(balt_tracts, balt) %>% lengths > 0,] %>% 
  tm_shape() + tm_polygons(col = "GEOID")

enter image description here

我注意到的一件事是st_touches()仅返回三个多边形。这是一个精度问题吗?或者这是否意味着人口普查区域的边界实际上并未与较大的多边形的边界完全对齐?

 balt_tracts[st_touches(balt_tracts, balt) %>% lengths > 0,] %>% 
   tm_shape() + tm_polygons(col = "GEOID")

enter image description here

2 个答案:

答案 0 :(得分:3)

在您的特定示例中,您应该只向county提供一个get_acs()参数,因为巴尔的摩市是一个独立的实体:

library(tidyverse)
library(sf)
library(tidycensus)
library(tigris)
library(tmap)

balt_tracts <- get_acs(geography = "tract",
                       variables = "B01003_001E", # population
                       year = 2018,
                       state = "Maryland",
                       county = "Baltimore city",
                       survey = "acs5",
                       geometry = TRUE) 

qtm(balt_tracts)

enter image description here

但是,您的更广泛的问题是一个值得解决的问题。如果您知道您的几何形状完美对齐(如果使用cb = TRUEcb = FALSE,则在同一年使用底格里斯河/ tidycensus时会保持一致),您可以使用sf::st_filter()st_within空间谓词一起进行空间子集。例如,假设我们要在巴尔的摩市区(完全在马里兰州)中抓取人口普查区域:

balt_metro <- core_based_statistical_areas(cb = TRUE, 
                                           year = 2018, 
                                           class = "sf") %>%
  filter(str_detect(NAME, "Baltimore"))

balt_metro_tracts <- tracts("MD", cb = TRUE, 
                            year = 2018, class = "sf") %>%
  st_filter(balt_metro, .predicate = st_within)

ggplot() + 
  geom_sf(data = balt_metro_tracts, fill = "white") + 
  geom_sf(data = balt_metro, fill = NA, color = "red")

enter image description here

答案 1 :(得分:1)

一种选择是将每个区域变成一个点并在其上相交,这消除了给我带来麻烦的重合边界。这种方法不需要像初始问题中那样选择任意的缓冲距离。

st_point_on_surface()st_centroid()更可取,因为它可以保证点位于多边形的表面上,而某些多边形的质心位于其表面之外。

balt_tracts[st_point_on_surface(balt_tracts)[balt,],] %>% 
  qtm()

enter image description here

相关问题