'Hot to get clean polygons in R after st_combine/st_union with sf package?

I have a tidy dataset for census sectors in sf format (setores_sp_ok.rda), which has polygons for two different territorial models, indicated by variable modelo. I want to aggregate census sectors by modelo and cnes, to create another dataset with new boundaries.

I can do this using group_by() + summarise() technique, which automatically uses st_union() to aggregate polygons. But the result is poor, with many internal boundaries.

# load packages
library(dplyr)
library(ggplot2)
library(sf)
library(lwgeom)

# import data
load(url("https://github.com/bruno-pinheiro/app_acesso_saude/raw/master/data/setores_sp_ok.rda"))

# combine polygons
ubs_malhas <- setores_sp %>% 
  st_make_valid() %>% 
  group_by(cnes, modelo) %>% 
  summarise(area = sum(area)) %>% 
  ungroup()

# plot
ggplot(ubs_malhas[ubs_malhas$modelo == "vigente", ]) +
  geom_sf(lwd = .2)

result have many internal boundaries

I know that is possible to realize this kind of operation combining st_combine, st_union and st_intersect, but I'm not realizing how to make it.

How to combine polygons by modelo and cnes and get clean aggregated polygons, without internal boundaries?

Someone has any tip?

Many thanks!

rsf


Solution 1:[1]

Your data may be tidy in a tidyverse sense, but the geometries certainly aren't. The borders between the "vigente" modelo units don't quite line up in many cases, hence you get these little "leftovers" caused by gaps between units. I would snap those to a grid of, say 1cm, and then call st_union.

# load packages
library(dplyr)
library(ggplot2)
library(sf)
library(lwgeom)

# import data
load(url("https://github.com/bruno-pinheiro/app_acesso_saude/raw/master/data/setores_sp_ok.rda"))

# combine polygons
ubs_malhas <- setores_sp %>% 
  st_snap_to_grid(size = 0.01) %>%
  st_make_valid() %>% 
  group_by(cnes, modelo) %>% 
  summarise(area = sum(area)) %>% 
  ungroup()

# plot
ggplot(ubs_malhas[ubs_malhas$modelo == "vigente", ]) +
  geom_sf(lwd = .2)

In case you still have unwanted polygons left, you may have to increase the grid size or delete those manually, e.g. in QGIS or thelike.

Solution 2:[2]

The function

    nngeo::st_remove_holes(your_sf_object)

Solve your problem.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 TimSalabim
Solution 2 Marco Antonio Faganello