对分组对象执行 sf 操作

Executing sf operations on grouped objects

我正在尝试按组查找相交的 sfc_LINESTRING,其中两个相交的 sfc_LINESTRING 对象被分组。这个问题具体涉及 st_intersects,但我认为 sf 中的其他操作的工作流程是相同的。类似的问题已经得到回答 here and here,但在这两种情况下,只有一个相交对象被分组,无论如何我都不够聪明,无法让它适用于我的数据集。

library(tidyverse)
library(sf)

line1 <- data.frame(lon = c(1, 1.5, 2, 2.5, 2.0, 2.5),
                lat = c(1, 1.5, 2, 2.5, 2.1, 2.6),
                grp = c("A", "A", "B", "B", "C", "C")
                ) %>% 
  st_as_sf(coords = c("lon","lat"), dim = "XY") %>% 
  group_by(grp) %>% 
  summarise(do_union = FALSE) %>% 
  st_cast("LINESTRING") %>% 
  mutate(grp = c("A","A","B"))

line2 <- data.frame(lon = c(1.2, 1.3, 2.2, 2.3),
                lat = c(1, 1.5, 2, 2.5),
                grp = c("A", "A", "B", "B")
                ) %>% 
  st_as_sf(coords = c("lon","lat"), dim = "XY") %>% 
  group_by(grp) %>% 
  summarise(do_union = FALSE) %>% 
  st_cast("LINESTRING")

plot(line1, lwd = 2, key.pos = 4, reset = FALSE)
plot(line2, lwd = 2, lty = 2, add = TRUE)

我现在想找到相关组的相交 sfc_LINESTRING。不幸的是,我希望使用 group_by 的简单解决方案会引发错误:

int <- line1 %>% 
  group_by(grp) %>% 
  filter(lengths(st_intersects(line1, line2)) >0)

使用我的实际数据集,我可以得到它到 运行,但是 group_by 命令似乎被忽略了,所以我得到了所有相交的对象,而不仅仅是那些按组匹配的对象.具体来说,在这种情况下,每个组的结果应该只有 select 个 sfc_LINESTRING,即匹配连续的绿色虚线和匹配的连续红色虚线。红色虚线不应与绿线相交。任何建议将不胜感激。

不完全确定我是否正确理解了您的要求,但我正在试一试!因此,请使用 sf 库的 st_join() 函数找到以下一种可能的解决方案,然后使用一些 dplyr 函数来获得最终结果。

Reprex

  • 代码
library(dplyr)
library(sf)

results <- line1 %>% 
  st_join(., line2, join = st_intersects) %>% 
  filter(., grp.x == grp.y) %>% 
  rename(grp = grp.x) %>% 
  select(-grp.y)
  • 输出
results
#> Simple feature collection with 2 features and 1 field
#> Geometry type: LINESTRING
#> Dimension:     XY
#> Bounding box:  xmin: 1 ymin: 1 xmax: 2.5 ymax: 2.6
#> CRS:           NA
#> # A tibble: 2 x 2
#>   grp           geometry
#>   <chr>     <LINESTRING>
#> 1 A       (1 1, 1.5 1.5)
#> 2 B     (2 2.1, 2.5 2.6)
  • 可视化
plot(results)


PS: 如果您想在同一个 sf 对象中获得每个组中的两条相交线,您可以将代码扩展为如下:

  • 补码
results2 <- results %>% 
  st_union(.,line2, by_feature = TRUE) %>% 
  filter(., grp == grp.1) %>% 
  select(-grp.1)
#> Warning: attribute variables are assumed to be spatially constant throughout all
#> geometries
  • 输出 2
results2
#> Simple feature collection with 2 features and 1 field
#> Geometry type: MULTILINESTRING
#> Dimension:     XY
#> Bounding box:  xmin: 1 ymin: 1 xmax: 2.5 ymax: 2.6
#> CRS:           NA
#> # A tibble: 2 x 2
#>   grp                                                                   geometry
#>   <chr>                                                        <MULTILINESTRING>
#> 1 A     ((1 1, 1.25 1.25), (1.25 1.25, 1.5 1.5), (1.2 1, 1.25 1.25), (1.25 1.25~
#> 2 B     ((2 2.1, 2.275 2.375), (2.275 2.375, 2.5 2.6), (2.2 2, 2.275 2.375), (2~
  • 可视化
plot(results2)

reprex package (v2.0.1)

于 2022-01-04 创建