R语言:查找数据框中与其他经纬度距离≤0.005的位置
在R中筛选存在近邻经纬度的点
先明确需求
我理解你要找的是存在至少一个其他经纬度点,与该点的经度差绝对值≤0.005且纬度差绝对值≤0.005的所有位置。如果实际需求是“与所有其他点都满足该距离条件”,可以补充说明后再调整方案。
示例数据
先构造可复现的示例数据框,方便你测试代码:
set.seed(123) df <- data.frame( lon = runif(10, min = 110, max = 111), lat = runif(10, min = 30, max = 31) )
方法1:基础R实现(适合小数据量)
通过自定义函数逐个检查每个点是否存在符合条件的近邻:
# 定义函数:检查第i个点是否有符合条件的近邻 has_close_neighbor <- function(i, df) { others <- df[-i, ] # 排除当前点自身 lon_diff <- abs(df$lon[i] - others$lon) lat_diff <- abs(df$lat[i] - others$lat) # 判断是否存在至少一个点满足两个差值都≤0.005 any(lon_diff <= 0.005 & lat_diff <= 0.005) } # 给每个点标记是否有近邻 df$has_close <- sapply(1:nrow(df), has_close_neighbor, df = df) # 筛选出符合条件的点 result <- df[df$has_close, ]
方法2:tidyverse实现(代码更直观)
用tidyverse的交叉连接和分组统计,逻辑清晰易读:
library(tidyverse) # 先给每个点加行号,避免和自身匹配 df <- df %>% mutate(id = row_number()) # 生成所有两两组合,排除自身对,计算距离差并判断是否近邻 cross_df <- df %>% cross_join(df, suffix = c("", "_other")) %>% filter(id != id_other) %>% mutate( lon_diff = abs(lon - lon_other), lat_diff = abs(lat - lat_other), is_close = lon_diff <= 0.005 & lat_diff <= 0.005 ) # 分组筛选出存在至少一个近邻的点 result <- cross_df %>% group_by(id, lon, lat) %>% summarise(has_close = any(is_close), .groups = "drop") %>% filter(has_close) %>% select(-id, -has_close)
方法3:data.table实现(适合大数据量)
如果你的数据行数较多(比如上万行),用data.table的方法效率会显著提升:
library(data.table) dt <- as.data.table(df) dt[, id := .I] # 添加行号标记每个点 # 生成所有两两组合,排除自身 cross_dt <- dt[dt, on = .(), allow.cartesian = TRUE][id != i.id] # 计算距离差并判断是否近邻 cross_dt[, `:=`( lon_diff = abs(lon - i.lon), lat_diff = abs(lat - i.lat), is_close = lon_diff <= 0.005 & lat_diff <= 0.005 )] # 筛选出存在近邻的点 result <- cross_dt[, .(has_close = any(is_close)), by = .(lon, lat)][has_close == TRUE][, has_close := NULL]
内容的提问来源于stack exchange,提问作者TwentyandChange
相关产品推荐
相关产品推荐

