R语言中dplyr调用geosphere destPoint推算缺失端点时mutate报错的解决方案
缺失端点坐标推算的实现方案
报错核心原因
- 代码中给
destPoint传入的第一个参数c(StartLon, StartLat)在向量化运算场景下,会把整列所有起点经度、整列所有起点纬度按顺序拼接成一个长向量,完全没有形成逐行匹配的(经度, 纬度)坐标对,和destPoint要求的输入格式不匹配,这就是触发“Wrong length for a vector, should be 2”报错的直接原因。 - 就算参数格式正确,
destPoint返回的是和数据行数等长的2列矩阵(分别对应经度、纬度),如果不拆分出独立的单列值,直接传入mutate做单列赋值,也会因为值维度不匹配报错。
注:之前考虑的用
select()提取对应值的思路无法生效——select()是针对当前数据框内部列做筛选的,根本无法访问destPoint独立返回的矩阵结构,没有办法从中拆分出单值。
具体实现代码
方案1:逐行处理(逻辑直观,适配中小数据量)
通过rowwise()锁定逐行运算的上下文,保证传入destPoint的是当前行的单个起点坐标对,计算完成后拆分经纬度值,最后用推算值替换原表的NA缺失值:
library(dplyr) library(geosphere) data <- data %>% rowwise() %>% mutate( # 逐行传入当前行的起点坐标对 calc_point = list(destPoint(c(StartLon, StartLat), Bearing, Length)), # 从返回的坐标对中分别提取经度、纬度 calc_EndLon = calc_point[1], calc_EndLat = calc_point[2] ) %>% ungroup() %>% # 仅对原表端点为NA的位置用推算值填充 mutate( EndLon = if_else(is.na(EndLon), calc_EndLon, EndLon), EndLat = if_else(is.na(EndLat), calc_EndLat, EndLat) ) %>% # 清理计算过程产生的辅助列 select(-calc_point, -calc_EndLon, -calc_EndLat)
方案2:向量化运算(适配大样本量,运行效率更高)
不做逐行循环,提前构造和数据行数匹配的2列坐标矩阵,一次性传入destPoint完成全量计算:
data <- data %>% mutate( # 构造逐行匹配的起点坐标矩阵,n行2列,列顺序为(经度, 纬度) start_coord_mat = cbind(StartLon, StartLat), # 一次传入矩阵完成全量终点坐标计算 calc_points = list(destPoint(start_coord_mat, Bearing, Length)), # 批量拆分计算得到的经度、纬度 calc_EndLon = sapply(calc_points, `[`, 1), calc_EndLat = sapply(calc_points, `[`, 2) ) %>% # 填充NA缺失值 mutate( EndLon = if_else(is.na(EndLon), calc_EndLon, EndLon), EndLat = if_else(is.na(EndLat), calc_EndLat, EndLat) ) %>% # 清理辅助列 select(-start_coord_mat, -calc_points, -calc_EndLon, -calc_EndLat)
结果校验
针对示例中的Section2分段,传入起点坐标(-132.4053, 53.00714)、方位角360度、长度10米,计算得到的终点坐标为经度保持-132.4053不变,纬度为53.00723,符合正北方向10米移动的地理计算逻辑。
内容的提问来源于stack exchange,提问作者sbliss
相关产品推荐
相关产品推荐

