[GIS] Removing empty polygon from sf object in R

polygonrsf

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.

Best Answer

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
>