You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何st_join(x,y,left=TRUE)返回的sf对象要素数多于输入x?

关于sf包st_join()函数关联多边形属性的问题解答

我有两个包含多个多边形(POLYGON)要素的sf对象,希望通过多边形空间关系将两者的属性关联起来。使用st_join()函数时,默认结果与预期不符,但添加largest = TRUE参数后得到了正确输出,想了解背后的原因。

示例代码

library(sf)
library(tidyverse)

map1 <- st_as_sfc(c("POLYGON((0 0 , 0 1 , -1 1 , -1 0, 0 0))",
                    "POLYGON((0 0 , 0 2 , 2 2 , 2 0, 0 0 ))", 
                    "POLYGON((0 0 , 0 -0.5 , -0.5 -0.5 , -0.5 0, 0 0))")) %>% 
  st_sf(ID = paste0("poly", 1:3),
        att1 = c(letters[1:3]))

map2 <- st_as_sfc(c("POLYGON((0 0 , 0 0.5 , -0.5 .5 , -0.5 0, 0 0))",
                    "POLYGON((-0.5 0 , -0.5 1 , -1 1 , -1 0 , -0.5 0))",
                    "POLYGON((0 0 , 0 1 , 1 1 , 1 0 , 0 0))",
                    "POLYGON((1 1 , 1 2 , 2 2 , 2 1 , 1 1))",
                    "POLYGON((0 0 , 0 -0.25 , -0.25 -0.25 , -0.25 0 , 0 0))")) %>% 
  st_sf(ID = paste0("poly", 4:8)) %>%
  mutate(att2 = c(LETTERS[1:5]))

# 默认调用st_join,结果不符合预期
map3 <- st_join(map2, map1, left = TRUE)

默认结果的问题

默认运行后得到12条要素,而非预期的5条,部分逻辑上不应该关联的多边形也被匹配:

Simple feature collection with 12 features and 4 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: -1 ymin: -0.25 xmax: 2 ymax: 2
CRS:           NA
First 10 features:
     ID.x att2  ID.y att1                              .
1   poly4    A poly1    a POLYGON ((0 0, 0 0.5, -0.5 ...
1.1 poly4    A poly2    b POLYGON ((0 0, 0 0.5, -0.5 ...
1.2 poly4    A poly3    c POLYGON ((0 0, 0 0.5, -0.5 ...
2   poly5    B poly1    a POLYGON ((-0.5 0, -0.5 1, -...
2.1 poly5    B poly3    c POLYGON ((-0.5 0, -0.5 1, -...
3   poly6    C poly1    a POLYGON ((0 0, 0 1, 1 1, 1 ...
3.1 poly6    C poly2    b POLYGON ((0 0, 0 1, 1 1, 1 ...
3.2 poly6    C poly3    c POLYGON ((0 0, 0 1, 1 1, 1 ...
4   poly7    D poly2    b POLYGON ((1 1, 1 2, 2 2, 2 ...
5   poly8    E poly1    a POLYGON ((0 0, 0 -0.25, -0....

为什么默认结果不符合预期?

st_join()的默认空间连接规则是**st_intersects(空间交集)**,只要两个几何对象有任何形式的重叠(包括共享顶点、边界线接触),就会生成一条关联记录。

在示例中,map1的三个多边形都共享原点(0,0),而map2的所有多边形都包含这个原点,因此每个map2的多边形都会和map1中所有包含原点的多边形(即全部3个)产生交集匹配,最终导致单条map2要素对应多条map1属性,结果行数远超预期。

为什么largest = TRUE能解决问题?

当设置largest = TRUE时,st_join()会为每个x(这里是map2)要素只匹配与之重叠面积最大的y(这里是map1)要素。这样即使一个x要素和多个y要素有交集,最终也只会保留重叠面积最大的那一组关联,从而保证结果的要素数和x一致(在left = TRUE的前提下)。

另一种解决方案:严格匹配“完全包含”

如果需求是严格判断map2的多边形完全被包含在map1的多边形中,可以指定join = st_within,这样只有满足完全包含关系的要素才会被关联:

map5 <- st_join(map2, map1, left = TRUE, join = st_within)

运行后同样会得到5条要素,符合预期。

内容的提问来源于stack exchange,提问作者baobab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 14:31:00