R – Can dplyr::group_by Work with sf::st_intersects in R

groupingrsfst-intersects

Trying to combine dplyr::group_by and sf::st_intersects to see which of the objects within groups in a sf dataframe are intersecting with each other but in the end all objects are compared with all objects in the dataframe irrespective of the groups.

It would be very useful if there is another option package/baseR to do this and limit the comparison of objects within the dataframe and only within a specified group.

Below I have done:
1. create a LINESTRING and a POLYGON
2. used sf::st_intersection to find parts of LINESTRING in the POLYGON
3. convert to LINESTRING
4. check which of the LINESTRINGs are intersecting with each other

library(sf)
library(dplyr)

# sample data
poly <- data.frame(lon = c(-3.5, -1.5, -1.5, -0.5, -0.5, 1, 1, 1.5, 1.5, 7, 7, -3.5, -3.5),
               lat = c(0, 0, 1, 1, 0, 0,1,1,0, 0, 2, 2, 0),
               var = 1) %>%
st_as_sf(coords = c("lon", "lat"), dim = "XY") %>% group_by(var) %>%
summarise(geometry = st_union(geometry), do_union = F) %>% st_cast("POLYGON")

line <- data.frame(lon = c(-4, -3, -2, -2, -3, 2, 2.5, 2, 2), lat = c(0.5, 0.5, 1, 0.5, 1, 0.2, 0.3, 0.4, 0.1), var = 1) %>%
st_as_sf(coords = c("lon", "lat"), dim = "XY") %>% group_by(var) %>%
summarise(geometry = st_union(geometry), do_union = F) %>% 
st_cast("MULTILINESTRING")

# calculating intersection of line with polygon
inters <- st_intersection(line,poly) %>% st_cast("LINESTRING")
inters <- inters %>% mutate(var = c(1,1,2,2,2,2,2,2,2,2,2))

# trying to see which of the linestrings intersect with each other
inters$flag <- inters %>% group_by(var) %>% st_intersects()

This should calculate the intersections between the first two LINESTRINGs separately and between the last 9 LINESTRINGs separately. So intersections of the first LINESTRING with any of the LINESTRINGs from 3 to 11 shouldn`t be calculated.

Best Answer

try this, using lapply and split instead of group_by:

inters$flag <- sapply(split(inters, inters$var), function(x) st_intersects(x)) %>% unlist(recursive = FALSE)