如何正确计算GPS动物追踪数据中的圆周航向差值?
正确计算GPS动物追踪数据中环形航向差值的方法
问题描述
我有带航向信息的GPS动物追踪数据,想要计算每日航向变化,以此判断动物长距离迁徙时是否保持单一方向。原始数据如下:
individual.id date heading 1 2020-12-16 150 1 2021-02-15 352 1 2021-10-27 211 1 2021-10-28 22 1 2021-10-29 235 1 2021-10-30 340 1 2021-11-02 5
尝试用R语言circular包处理的代码如下:
direction <- df %>% group_by(individual.id) %>% mutate(heading = circular(heading, units = "degrees", template= "geographics"), heading.diff=heading-lag(heading))
得到的结果中,环形边界的差值不符合实际(比如从340度到5度,计算出335度,但实际最短路径是25度):
individual.id date heading heading.diff 1 2020-12-16 150 NA 1 2021-02-15 352 202 1 2021-10-27 211 141 1 2021-10-28 22 189 1 2021-10-29 235 213 1 2021-10-30 340 105 1 2021-11-02 5 335
普通绝对值计算也无法解决问题:
direction <- df%>% group_by(individual.id) %>% mutate(heading.diff=abs(heading-lag(heading)))
期望的正确差值结果应为:
individual.id date heading heading.diff 1 2020-12-16 150 NA 1 2021-02-15 352 158 1 2021-10-27 211 141 1 2021-10-28 22 171 1 2021-10-29 235 147 1 2021-10-30 340 105 1 2021-11-02 5 25
解决方案
方法1:使用circular包的diff.circular()函数
circular包内置了专门处理环形数据差值的diff.circular()函数,会自动计算两个航向之间的最短路径角度差。修改代码如下:
library(circular) library(dplyr) direction <- df %>% group_by(individual.id) %>% mutate(heading = circular(heading, units = "degrees", template = "geographics"), heading.diff = c(NA, diff.circular(heading))) %>% ungroup()
该函数会自动处理0/360度的循环边界问题,直接输出符合预期的最短路径差值。
方法2:手动计算环形差值
如果不想依赖circular包,可以通过数学逻辑手动计算最短路径角度差:
library(dplyr) direction <- df %>% group_by(individual.id) %>% mutate(heading.diff = abs(heading - lag(heading)), heading.diff = ifelse(heading.diff > 180, 360 - heading.diff, heading.diff)) %>% ungroup()
原理:若两个角度的绝对值差大于180度,说明最短路径是走环形的另一侧,用360减去当前差值即可得到正确的最短角度变化。
内容的提问来源于stack exchange,提问作者SGinel
相关产品推荐
相关产品推荐

