匹配两个DataFrame近似经纬度,填充对应Marketname列
问题与解决方案
问题描述
我有两个包含经纬度的DataFrame,需要对比两者的经纬度进行近似匹配:当两个DataFrame中的经纬度前5位数值一致(例如纬度取-22.892、经度取-48.450,即四舍五入到3位小数后相等)时,将DataFrame x的Marketname填入DataFrame y对应行的Marketname列。
原始数据
DataFrame x:
x <- structure(list(Latitude = c(-22.8928950233225, -22.929618895716, -22.8773751675936), Longitude = c(-48.4504779883472, -48.4515412645053, -48.4364903609011), Marketname = c("Market1", "Market2", "Market3")), row.names = c(NA, 3L), class = "data.frame")
输出:
> x Latitude Longitude Marketname 1 -22.89290 -48.45048 Market1 2 -22.92962 -48.45154 Market2 3 -22.87738 -48.43649 Market3
DataFrame y(初始状态):
y <- structure(list(lat = c(-22.8715263, -22.8774825, -22.8928723, -22.9295906), lng = c(-48.440335, -48.4364964, -48.4507477, -48.4516264 ), Marketname = c("Market0","0", "0", "0")), row.names = c(NA, 4L), class = "data.frame")
输出:
> y lat lng Marketname 1 -22.87153 -48.44033 Market0 2 -22.87748 -48.43650 0 3 -22.89287 -48.45075 0 4 -22.92959 -48.45163 0
预期输出
> y lat lng Marketname 1 -22.87153 -48.44033 Market0 2 -22.87748 -48.43650 Market3 3 -22.89287 -48.45075 Market1 4 -22.92959 -48.45163 Market2
解决方案
核心思路是将经纬度四舍五入到3位小数(保证前5位数值一致),再进行匹配填充。
方法1:基础R实现
# 为x生成匹配键(经纬度保留3位小数) x$lat_key <- round(x$Latitude, 3) x$lng_key <- round(x$Longitude, 3) # 为y生成匹配键 y$lat_key <- round(y$lat, 3) y$lng_key <- round(y$lng, 3) # 通过拼接键值对进行匹配,填充Marketname match_pos <- match(paste(y$lat_key, y$lng_key), paste(x$lat_key, x$lng_key)) y$Marketname[!is.na(match_pos)] <- x$Marketname[match_pos[!is.na(match_pos)]] # 移除临时生成的键列 y <- y[, !names(y) %in% c("lat_key", "lng_key")] # 查看结果 print(y)
方法2:tidyverse/dplyr实现
如果习惯使用tidyverse生态,用左连接更直观:
library(dplyr) # 预处理x,生成带匹配键的数据集 x_clean <- x %>% mutate(lat_key = round(Latitude, 3), lng_key = round(Longitude, 3)) %>% select(lat_key, lng_key, Marketname) # 处理y,连接后替换Marketname y_final <- y %>% mutate(lat_key = round(lat, 3), lng_key = round(lng, 3)) %>% left_join(x_clean, by = c("lat_key", "lng_key")) %>% # 保留原有非空的Marketname,填充匹配到的名称 mutate(Marketname = ifelse(is.na(Marketname.y), Marketname.x, Marketname.y)) %>% select(lat, lng, Marketname) # 查看结果 print(y_final)
内容的提问来源于stack exchange,提问作者Carlo Soares
相关产品推荐
相关产品推荐

