You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 14:47:19