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

R语言基于空间相交匹配实现同门店坐标数据合并

多源门店坐标匹配聚合实现方案

你的思路逻辑成立,核心需要补全两个容易踩坑的点:一是空间缓冲区计算必须转米制投影,不能直接在经纬度坐标下生成缓冲区;二是两两空间相交的结果需要做连通性聚类,才能把「A与B相交、B与C相交但A与C不直接相交」的同门店点归到同一组。

完整实现流程

  • 加载依赖包,将原始数据转为sf空间对象,转换为米制投影后生成100米半径缓冲区
  • 按清洗后的name_key字段分组,组内计算所有缓冲区的空间相交关系
  • 将相交关系转为无向图,通过连通分量识别生成唯一group_id,同一连通分量下的点对应同一个实体门店
  • 按group_id聚合所有关联品牌,完成匹配

可直接运行的测试代码

library(tidyverse)
library(sf)
library(igraph)

# 原始测试数据
tt <- tibble(lat  = c(41.38702918, 41.386601, 41.38744179, 41.3871449, 41.38896353, 41.38963478, 41.38666041, 41.38598465, 41.3867169, 41.3852132453, 41.38438262),
             long = c(2.170086301, 2.16939207, 2.17080332, 2.171450558, 2.167685415, 2.16892721, 2.170950285, 2.171100009, 2.171736392, 2.171215346, 2.170955304),
             name = c( "El Corte Inglés", "EL CORTE INGLÉS DIAGONAL (007)", "El Corte Inglés", "El Corte Inglés Barcelona", "Nadons", "Pops And Co", "Bitti", "BITTI", "BITTI", "Bitti", "Bitti"),
             brand = c( "b", "s", "c", "e", "e", "c", "m", "c", "s", "e", "b") ) %>% 
  mutate(name_key = tolower(name),
         name_key = iconv(name_key, from="UTF-8",to="ASCII//TRANSLIT"),
         name_key = str_remove_all(name_key, '[[:digit:]]'),
         name_key = str_remove_all(name_key, '[:punct:]'), 
         name_key = str_remove_all(name_key, '[:space:]'),
         name_key = str_remove_all(name_key, 'ltda'),
         name_key = str_remove_all(name_key, 'ltd'),
         name_key = str_sub(name_key, end = 5L),
         # 给原始数据加行号作为唯一点id
         point_id = row_number())

# 生成空间对象、转米制投影、做100米缓冲区
# 测试样本位于巴塞罗那,对应米制投影选EPSG:25831,国内数据可换对应区域的UTM或CGCS2000投影
tt_sf <- tt %>%
  st_as_sf(coords = c("long", "lat"), crs = 4326) %>%
  st_transform(crs = 25831) %>%
  mutate(buffer = st_buffer(geometry, dist = 100))

# 按name_key分组计算连通组id
tt_with_group <- tt_sf %>%
  group_by(name_key) %>%
  group_modify(~{
    # 组内点数小于等于1直接返回,group_id为自身point_id
    if(nrow(.x) <=1) {
      return(.x %>% mutate(group_id = point_id))
    }
    # 计算组内缓冲区的相交邻接矩阵
    intersect_mat <- st_intersects(.x$buffer, .x$buffer, sparse = F)
    # 构建无向图,找连通分量
    g <- graph_from_adjacency_matrix(intersect_mat, mode = "undirected", diag = F)
    comp <- components(g)$membership
    # 生成全局唯一group_id:name_key + 组内分量id
    .x %>% mutate(group_id = paste0(.y$name_key, "_", comp))
  }) %>%
  ungroup()

# 按group_id聚合所有入驻品牌
store_brand_map <- tt_with_group %>%
  st_drop_geometry() %>%
  group_by(group_id) %>%
  summarise(
    all_brands = paste0(unique(brand), collapse = ","),
    store_names = paste0(unique(name), collapse = " | "),
    point_count = n()
  )

# 如果需要可视化验证,可直接用之前的leaflet代码,把group_id加到label里即可

参数调整说明

  • 缓冲区半径:根据你爬取的多源数据坐标偏差幅度调整,若多数同门店点偏差在50米内可设为50,偏差大可适当上调,避免把相邻的不同门店误合并
  • name_key清洗规则:可根据你的数据特征新增清理规则,比如去掉"inc"、"shop"、"store"等通用后缀,进一步降低误匹配概率
  • 性能优化:如果数据量超过10万条,按name_key分组后再做空间计算的逻辑已经能大幅降低计算量,不需要全局做空间相交匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 23:42:44