Skip to content

[BUG] fsubset does not recompute attributes properly in some cases of subsetting sf objects #848

Description

@MGousseff

Describe the bug
When using fsubset to subset an sf objects with mixed geoms, the attributes of geometries are not updates

Steps/Code to Reproduce
Function to create reproducible example :

make_square <- function(cx, cy, size = 0.5) {
  st_polygon(list(rbind(
    c(cx - size, cy - size),
    c(cx + size, cy - size),
    c(cx + size, cy + size),
    c(cx - size, cy + size),
    c(cx - size, cy - size)  # close the ring
  )))
}

Create mixed geoms and dataset that make fsubset fail

mixed_geom <- st_sfc(
  make_square(1, 1),
  make_square(2, 1),
  st_union(make_square(3, 1), make_square(3.5, 1)),  # creates MULTIPOLYGON
  make_square(1, 2),
  make_square(2, 2),
  make_square(3, 2),
  crs = 4326
)

exampleSf <- st_sf(
  var      = factor(c("A", "B", "C", "A", "B", "C")),
  group    = factor(c("g1", "g1", "g1", "g2", "g2", "g2")),
  geometry = mixed_geom
)

Compare results between subset and fsubset

test1 <- collapse::fsubset(exampleSf, group == "g1")
test2 <- exampleSf[exampleSf$group == "g1", ]

expect_identical(test1$geometry, test2$geometry)

In fact, some attributes of the subset object are in fact those of the original object

attributes(tetest1$geometry)$bbox
# returns 
# xmin ymin xmax ymax 
#  0.5  0.5  4.0  2.5 
# which is the bbox of the original object
attributes(tetest2$geometry)$bbox
# returns
# xmin ymin xmax ymax 
#  0.5  0.5  4.0  1.5 
# the proper bbox of the subset

In this minimal reprex, there is almost no consequence, but for some more complicated sf, the attributes classes keeps the one of the whols sf object, and it can break the use of ggplot2::geom_sf

Expected behavior
The attribute of the subset sf object should be updated an inherited

Additional context
It took me quite a long time to isolate the problem as it only happens with mixed geometry types, and worsen after grouping and degrouping. I realize this is a NICHE problem, and I would totally understand if it would not be judged worth it to fix it, but I'm doing my best to contribute to the fastverse and I love the class agnostic elegance of collapse, so I thought I'd share this.
For the moment my fix is to use dplyr::filter or base R subset.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions