1

I'm trying to aggregate a simple features collection using a group variable that is a factor. Below is a simple example.

library(sf)
#> Warning: package 'sf' was built under R version 4.2.3
#> Linking to GEOS 3.9.3, GDAL 3.5.2, PROJ 8.2.1; sf_use_s2() is TRUE

m1 = cbind(c(0, 0, 1, 1, 0), c(0, 1, 1,0, 0))
m2 = cbind(c(1, 2, 2, 1, 1), c(1, 1, 0,0, 1))
m3 = cbind(c(1, 1, 2, 2, 1), c(1, 2, 2,1, 1))
pol = st_sf(geometry = st_sfc(st_polygon(list(m1)), st_polygon(list(m2)), st_polygon(list(m3))))
pol$value = c(1,1,2)
pol
#> Simple feature collection with 3 features and 1 field
#> Geometry type: POLYGON
#> Dimension:     XY
#> Bounding box:  xmin: 0 ymin: 0 xmax: 2 ymax: 2
#> CRS:           NA
#>                         geometry value
#> 1 POLYGON ((0 0, 0 1, 1 1, 1 ...     1
#> 2 POLYGON ((1 1, 2 1, 2 0, 1 ...     1
#> 3 POLYGON ((1 1, 1 2, 2 2, 2 ...     2

With aggregate, I get the spatial features merged as I want, but I also get a duplicate version of by grouping variable.

aggregate(pol, by = list(pol$value), unique, drop = TRUE)
#> Simple feature collection with 2 features and 2 fields
#> Attribute-geometry relationship: 0 constant, 1 aggregate, 1 identity
#> Geometry type: POLYGON
#> Dimension:     XY
#> Bounding box:  xmin: 0 ymin: 0 xmax: 2 ymax: 2
#> CRS:           NA
#>   Group.1 value                       geometry
#> 1       1     1 POLYGON ((0 1, 1 1, 2 1, 2 ...
#> 2       2     2 POLYGON ((1 1, 1 2, 2 2, 2 ...

I have tried naming the items in the list passed to the -by- argument, but this just results in duplicate variable called Value.1 instead of Group.1.

I am aware that I can use group_by and summarise to get the result I want, but I would like to avoid dplyr if possible. I could just drop the unwanted variable, but I feel that I must be missing something obvious.

Created on 2023-08-10 with reprex v2.0.2

3
  • I don't think you are missing anything; in fact I believe this is a bug in sf package. Commented Aug 10, 2023 at 16:16
  • This is what aggregate() should return, the additional grouping variable in value is described in ?sf:::aggregate.sf() as well as in ?stats::aggregate() . Perhaps aggregate(pol, by = list(pol$value), unique, drop = TRUE) |> subset(select = -Group.1)
    – margusl
    Commented Aug 11, 2023 at 9:07
  • I was just surprised that there wasn't a way to do this without the extra (subset) step. But either using aggregate with subset or sf_dissolve, as suggested by Jeffrey Evan, both fit the bill.
    – RichPatter
    Commented Aug 14, 2023 at 7:21

1 Answer 1

0

If I get your gist, you want to dissolve the geometry of features sharing a common attribute. Correct? This can be done with the sf_dissolve function in spatialEco. To dissolve feature geometry and attributes it is unfortunately not as simple an using dplyr::aggregate (or base).

library(sf)
library(spatialEco)

m1 = cbind(c(0, 0, 1, 1, 0), c(0, 1, 1,0, 0))
m2 = cbind(c(1, 2, 2, 1, 1), c(1, 1, 0,0, 1))
m3 = cbind(c(1, 1, 2, 2, 1), c(1, 2, 2,1, 1))
pol = st_sf(geometry = st_sfc(st_polygon(list(m1)), st_polygon(list(m2)), st_polygon(list(m3))))
pol$value = c(1,1,2) 

( dpol <- sf_dissolve(pol, "value") )
  plot(dpol)

dissolved features

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.