'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)
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!
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 |