The documentation of the st_union function of sf is not clear (for me!) on one point: what are the action and result of the function when applied to an sfc with a single feature, with the parameter by_feature=FALSE (default)? It seems that, according to the text of the documentation, nothing should happen and that the value returned should be the same as the one-feature sfc provided.

I ask this question because it is rather common to find proposals, advices for chaining st_union to st_combine, especially in the context of the use of st_difference (see the sf manual, at geos_binary_ops, or ?st_intersection):

the use of "st_difference(SF1,st_union(st_combine(SF2)))" is proposed.

Two questions in order to understand:

. Because st_combine returns a single-feature sfc, how could st_union have any effect on such an object?

. Is there any simple case, any example, where st_union, with by_feature=FALSE, applied to a single sfc has any effect?

Extract of the documentation of st_union: "If st_union is called with a single argument, x, and by_feature is FALSE all geometries are unioned together and an sfg or single-geometry sfc object is returned. If by_feature is TRUE each feature geometry is unioned. This can for instance be used to resolve internal boundaries after polygons were combined using st_combine."


I might not have the correct language to exactly explain this, but I just discovered a case where using sf::st_combine before calling sf::st_union made a big difference to me.

I was using dplyr::group_by and dplyr::summarise to group an sf tibble by a certain variable and then union each group to a single sf object:

sf_tibble %>%
  dplyr::group_by(area) %>% 

However, what I ended up with was multipolygon geometries, which is fine, but it meant that when I plotted my shapes with text labels, I ended up with multiple text labels for each area. I only wanted a single text label.

Then I tried using st_combine first, then st_union, and this solved my issue. I now only get single text labels for each area. To be explicit:

sf_tibble %>%
  dplyr::group_by(area) %>% 
  dplyr::summarise(across(geometry, ~ sf::st_combine(.)), .groups = "keep") %>% 
  dplyr::summarise(across(geometry, ~ sf::st_union(.)), .groups = "drop")

[It may be that a plain dplyr::summarise() is fine for one of those lines, and I'm not sure how important the .groups bits are.]


sf_tibble %>%
  dplyr::group_by(area) %>% 
  dplyr::summarise(across(geometry, ~ sf::st_combine(.)), .groups = "keep") %>%
  # dplyr::summarise(across(geometry, ~ sf::st_union(.)), .groups = "drop")

seems to have the same effect as the code in the previous block.)

I realised that I might need to do this when I read that st_union

can be used to join overlapping and adjacent features

My areas were not all comprised of overlapping and adjacent features - some of them were coastal areas with separate islands. So then I realised that I maybe needed to combine the areas first, before unioning.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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