如何筛选邻近几何对象:美国邮编数据的10英里范围过滤
筛选指定邮编10英里范围内的美国ZCTA数据
需求说明
从包含美国所有ZCTA(邮编对应地理边界)的空间数据框中,筛选出距离邮编17954对应的ZCTA 10英里范围内的所有ZCTA,使用tigris获取ZCTA数据,dplyr和sf的st_filter()实现空间筛选。
原代码问题修正
原代码存在两个核心问题:
- 直接传入ZCTA编码字符串而非空间对象给
st_filter,导致筛选逻辑失效 - 未处理
dist参数的单位:tigris返回的ZCTA默认用WGS84地理坐标系(单位为度),直接传入10会被识别为10度,而非10英里
修正后的完整代码
library(tigris) library(dplyr) library(sf) library(units) # 从FoodAccessResearchAtlasData2019提取所有州 states = unique(FoodAccessResearchAtlasData2019$State) # 批量获取各州2010年ZCTA数据并合并 state_list = lapply(states, function(state) { zctas(state = state, year = 2010) }) zipcodes = do.call(rbind, state_list) # 定位目标邮编17954对应的空间对象 target_zip = zipcodes %>% filter(ZCTA5CE10 == "17954") # 筛选10英里范围内的ZCTA(用units包直接指定距离单位) nearby_zips = zipcodes %>% st_filter(target_zip, .predicate = st_is_within_distance, dist = set_units(10, miles))
替代方案(坐标系转换)
如果不想依赖units包,可以先将数据转换为以米为单位的投影坐标系,再将英里转换为米计算:
# 转换到适合美国东部的投影坐标系(EPSG:26918,单位米) zipcodes_proj = st_transform(zipcodes, 26918) target_zip_proj = st_transform(target_zip, 26918) # 10英里≈1609.34米 nearby_zips = zipcodes_proj %>% st_filter(target_zip_proj, .predicate = st_is_within_distance, dist = 10 * 1609.34)
关键注意点
- 必须确保
target_zip是sf空间对象,而非单纯的字符编码 - 如果目标邮编不存在,提前做判断(比如
if(nrow(target_zip) == 0))避免报错 - 处理全美国ZCTA数据时,可先过滤目标州周边的州,减少数据加载量提升效率
内容的提问来源于stack exchange,提问作者robdyrek
相关产品推荐
相关产品推荐

