TransWikia.com

Removing empty polygon from sf object in R?

Geographic Information Systems Asked on August 19, 2021

I have such object:

> p_mb
Simple feature collection with 52 features and 0 fields (with 9 geometries empty)
geometry type:  GEOMETRY
dimension:      XY
bbox:           xmin: 585001.4 ymin: 211001.9 xmax: 609998.1 ymax: 236998.6
epsg (SRID):    NA
proj4string:    NA
First 10 features:
                         geometry
1  POLYGON ((591051.4 211855, ...
2                   POLYGON EMPTY
3  POLYGON ((588206.4 212570, ...
4  MULTIPOLYGON (((585004.6 21...
5  POLYGON ((600614.5 216112.9...
6  POLYGON ((603033.8 215125.2...
7  MULTIPOLYGON (((608168.4 21...
8  POLYGON ((600009.4 212984, ...
9  POLYGON ((603203.4 217336, ...
10 POLYGON ((585519.4 217546, ...

obtained from negative buffering other sf object. My question is simple, how to delete those empty slots to not get error and warnings:

> p_pol <- sf::st_cast(p_mb0, "POLYGON")
There were 23 warnings (use warnings() to see them)
> warnings()
1: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
2: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
3: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
4: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
5: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
6: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
7: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
8: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
9: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
10: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
11: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
12: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
13: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
14: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
15: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
16: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
17: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
18: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
19: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
20: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
21: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
22: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only
23: In st_cast.MULTIPOLYGON(X[[i]], ...) : polygon from first part only

> spl_mbuf <- as(p_pol, "Spatial")
Error: length(srl) > 0 is not TRUE

I think I can skip those warnings.


Found workaround: just used p_uni <- sf::st_union(p_mb) after buffer, but this is only emergency exit.

2 Answers

My first guess was to use st_area and select for those with area greater than zero. But I looked at the docs and found st_is_empty. For example here's some constructed test data:

> p = st_point(c(1,1))
> pv = st_sfc(p,p,p,p,p)
> bv = st_buffer(pv, c(1,1,0,-1,2))
> d = st_sf(bv)
> d$ID=1:5

Which has two empty polygons:

> d
Simple feature collection with 5 features and 1 field (with 2 geometries empty)
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -1 ymin: -1 xmax: 3 ymax: 3
epsg (SRID):    NA
proj4string:    NA
                              bv ID
1 POLYGON ((2 1, 1.99863 0.94...  1
2 POLYGON ((2 1, 1.99863 0.94...  2
3                  POLYGON EMPTY  3
4                  POLYGON EMPTY  4
5 POLYGON ((3 1, 2.997259 0.8...  5

Get only the non-empty with:

> dne = d[!st_is_empty(d),,drop=FALSE]
> dne
Simple feature collection with 3 features and 1 field
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -1 ymin: -1 xmax: 3 ymax: 3
epsg (SRID):    NA
proj4string:    NA
                              bv ID
1 POLYGON ((2 1, 1.99863 0.94...  1
2 POLYGON ((2 1, 1.99863 0.94...  2
5 POLYGON ((3 1, 2.997259 0.8...  5
> 

Answered by Spacedman on August 19, 2021

Building off of the answer by @Spacedman, you can filter out empty geometries using st_is_empty with a tidyverse approach

dne <- d %>% filter(!st_is_empty(.))

Answered by Marcos on August 19, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP