德国邮政编码的最近邻匹配与距离计算技术需求问询
德国邮政编码数据集的最近邻匹配方案
需求说明
我有两个不同长度的德国邮政编码(PLZ)数据集,都包含经度(lon)和纬度(lat)信息。需要给第一个数据集中的每个邮政编码,在第二个数据集中找到对应的最近邻邮政编码,同时要拿到两者的距离数值,以及匹配到的目标邮政编码。
之前试过暴力计算所有200万种组合(10000个起点×200个终点),用geosphere包或者Google Maps工具算距离再筛最小值,但效率太低。现在打算用最近邻搜索算法,已经知道R语言的RANN包里的nn2()函数可以搞定,设置searchtype = "priority"就行,不用radius模式。
数据集示例
起点数据集(部分样本)
plz city lon lat 1 69115 Heidelberg 8.6934499740601 49.406078338623 2 44137 Dortmund 7.4582135 51.5143952 3 70178 Stuttgart 9.17115 48.77426 4 68159 Mannheim 8.4696736826668 49.491940248873 5 68167 Mannheim 8.4971965 49.5038859
目标数据集(部分样本)
plz city lon lat 1 76530 Baden-Baden 8.2423068 48.7438178 2 89081 Ulm 9.961367 48.4253282 3 69120 Heidelberg 8.6752461 49.4225417 4 72076 Tübingen 9.0406256 48.5312051 5 74523 Schwäbisch-Hall 9.7424451 49.1247435
具体实现步骤
1. 安装并加载依赖包
# 首次运行先装包 install.packages(c("RANN", "dplyr")) # 加载需要的包 library(RANN) library(dplyr)
2. 预处理数据
先确保两个数据集的经纬度列是数值型,避免后续报错:
# 转换经纬度为数值类型(如果原始数据是字符格式) df_start <- df_start %>% mutate(across(c(lon, lat), as.numeric)) df_target <- df_target %>% mutate(across(c(lon, lat), as.numeric))
3. 执行最近邻搜索
提取经纬度矩阵,用nn2()找每个起点的最近邻:
# 提取经纬度数据转成矩阵 start_coords <- df_start %>% select(lon, lat) %>% as.matrix() target_coords <- df_target %>% select(lon, lat) %>% as.matrix() # 运行最近邻搜索,k=1表示只找最近的1个 nn_result <- nn2(data = target_coords, query = start_coords, k = 1, searchtype = "priority")
4. 合并结果到原数据
把匹配到的目标PLZ和距离加到起点数据集里:
# 把最近邻的PLZ和距离赋值给原数据集 df_start$nearest_plz <- df_target$plz[nn_result$nn.idx[,1]] df_start$euclidean_distance <- nn_result$nn.dists[,1] # 查看结果 head(df_start)
补充:计算真实地理距离
如果需要更精准的球面距离(比如米为单位),可以用geosphere包在找到最近邻后计算:
# 安装并加载geosphere install.packages("geosphere") library(geosphere) # 计算哈维正弦距离(单位:米) df_start$geo_distance <- apply(df_start, 1, function(row) { target_row <- df_target[df_target$plz == row["nearest_plz"], ] distHaversine(c(row["lon"], row["lat"]), c(target_row$lon, target_row$lat)) })
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

