R sf包使用st_union合并重叠缓冲区后按学校统计各范围门店数的方法
解决方案
你当前的问题核心是重叠缓冲区的重复计数问题,用缓冲区相交的方式天然会重复统计重叠区域的门店,且合并缓冲区后会丢失学校归属信息,最优方案是先计算每间门店到所有学校的最短距离、匹配对应归属学校,再按距离阈值分类统计,完全避免重复计数问题。
完整实现代码
library(sf) library(dplyr) # 1. 计算所有门店到所有学校的距离矩阵(单位和你的utm坐标系一致,为米) dist_matrix <- st_distance(store.sf.utm, school.sf.utm) # 转成数据框,行对应门店,列对应学校 dist_df <- as.data.frame(dist_matrix) # 给列命名为学校名,将下方school_name替换为你school.sf.utm中存储学校名称的列名 colnames(dist_df) <- school.sf.utm$school_name # 2. 为每个门店匹配最近的学校和对应距离 store_assign <- store.sf.utm %>% mutate( # 最近的学校名称 nearest_school = colnames(dist_df)[max.col(-dist_df)], # 到最近学校的距离(转数值型) min_dist = as.numeric(do.call(pmin, dist_df)) ) # 3. 按规则统计每个学校的门店数 result <- store_assign %>% st_drop_geometry() %>% # 过滤2000米范围外的门店 filter(min_dist <= 2000) %>% # 按归属学校分组统计 group_by(nearest_school) %>% summarise( Stores1000m = sum(min_dist <= 1000), Stores2000m = n() ) %>% # 补全没有匹配到门店的学校,计数设为0 right_join(tibble(nearest_school = school.sf.utm$school_name), by = "nearest_school") %>% mutate(across(c(Stores1000m, Stores2000m), ~ifelse(is.na(.), 0, .))) %>% rename(School = nearest_school) # 输出结果 print(result)
代码说明
- 完全符合你的统计规则:重叠区域的门店只会归属到距离最近的学校,不会重复计数
- 自动补全没有匹配到门店的学校,不会遗漏数据
- 输出的字段格式完全匹配你要求的
School | Stores1000m | Stores2000m结构
内容的提问来源于stack exchange,提问作者revere2323
相关产品推荐
相关产品推荐

