R语言使用dplyr和geosphere按分组计算相邻行地理距离报错解决
报错原因
你的代码报错核心有两点:
- 在
dplyr管道的分组计算环境中,.代表的是传入管道的完整原始数据集,而非当前正在计算的分组切片,分组逻辑不会对.的子集操作生效。 - 你用
c(lon, lat)作为列索引子集数据时,没有正确适配dplyr的列引用规则,程序会直接读取lon、lat列存储的经纬度数值作为列下标,尝试用浮点数值索引列位置,才触发了「数值转整数丢失精度」的报错。
另外distGeo的参数需要逐行匹配当前点和上一个点的经纬度对,直接对多列数据框整体用lag也不符合函数的参数要求。
修正方案
方法1:dplyr 1.1.0+ 推荐写法(最简洁)
用pick()函数提取当前分组内的指定列,自动适配分组和逐行计算逻辑:
library(dplyr) library(geosphere) df %>% group_by(id) %>% arrange(date, .by_group = TRUE) %>% mutate( dist = distGeo( pick(lon, lat), lag(pick(lon, lat), default = slice(pick(lon, lat), 1)) ) )
代码说明:
pick(lon, lat)会在当前分组内逐行返回经纬度列,不需要写引号引用列名,也不会取到全量数据lag会将经纬度行整体滞后1位,每个分组的第一行用该组第一条记录的经纬度作为默认值,计算得到的第一行距离为0,符合「首日无行进距离」的常规逻辑- 计算得到的
dist单位为米,是WGS84坐标系下的地表实际距离。
方法2:兼容老版本dplyr的写法
如果使用的dplyr版本低于1.1.0没有pick函数,可以分别对经纬度列做滞后,再合并为坐标矩阵传入distGeo:
df %>% group_by(id) %>% arrange(date, .by_group = TRUE) %>% mutate( dist = distGeo( cbind(lon, lat), cbind(lag(lon, default = first(lon)), lag(lat, default = first(lat))) ) )
注意事项
如果你的经纬度不是WGS84坐标系(比如是GCJ02火星坐标系、BD09百度坐标系),需要先转成WGS84再用distGeo计算,否则结果会有偏差。
内容的提问来源于stack exchange,提问作者TKH_9
相关产品推荐
相关产品推荐

