使用sf包基于点对距离筛选点位时filter函数报错的解决求助
报错原因
st_distance()输入单组sf几何列时,返回的是n×n的距离矩阵(n为点位数量,你的场景n=10,矩阵总元素100)。你直接将整个矩阵传入mutate()生成dist列后,as.numeric(df.dist$dist)会把矩阵展平为长度100的向量,而filter()要求判断条件的长度和数据行数(10行)一致,因此触发维度不匹配报错。
另外注意:你当前用WGS84坐标系的df计算距离,返回的单位是度不是米,要拿到米为单位的欧氏距离,必须用你已经投影好的df.laea计算。
解决方案
方案1:生成点对长表筛选(最常用,输出所有符合要求的点对组合)
适合需要输出所有<点A, 点B>配对的场景,自动去重、排除点位和自身的配对:
library(tidyr) # 1. 用投影后的点位计算距离矩阵,单位为米 dist_mat <- st_distance(df.laea) # 2. 矩阵关联点位索引 rownames(dist_mat) <- colnames(dist_mat) <- seq_len(nrow(df.laea)) # 3. 转长表+筛选符合条件的点对 distance.target <- as.data.frame(dist_mat) %>% tibble::rownames_to_column("point1_id") %>% pivot_longer(-point1_id, names_to = "point2_id", values_to = "dist") %>% mutate( across(c(point1_id, point2_id), as.integer), dist = as.numeric(dist) ) %>% # point1_id < point2_id 避免重复配对(比如点1-点2和点2-点1重复),同时排除自身配对 filter(point1_id < point2_id, dist < 20000)
方案2:保留原始点位结构,每行存储对应点位的所有近邻
适合需要保留原始10行点位结构,每行关联该点位所有符合距离要求的其他点位的场景:
distance.target <- df.laea %>% mutate( # 每行存储当前点位对应的所有近邻的行索引 near_point_ids = purrr::map(st_distance(geometry), ~which(as.numeric(.x) < 20000)) )
内容的提问来源于stack exchange,提问作者Leprechault
相关产品推荐
相关产品推荐

