在R语言中识别并移除无效或错误的GPS空间点
批量清理GPS定位数据中的异常空间点
场景背景
你有35只动物的10万+条GPS数据,已经通过以下代码完成了初步清洗(移除NA和0值的经纬度):
library(dplyr) data <- data_all %>% filter(!is.na(LATITUDE), LATITUDE != 0,!is.na(LONGITUDE), LONGITUDE != 0)
但仍存在异常空间点(例如某条数据的LATITUDE=-78.6917357、LONGITUDE=17.5506138),尝试用精确值过滤无效,且无行号无法指定删除,需要支持管道函数的批量处理方案。
解决方案
1. 修复单条异常点的精确匹配问题
直接用!=匹配小数无效是因为浮点数精度误差,改用dplyr的near()函数做近似匹配:
data_clean <- data_all %>% filter(!is.na(LATITUDE), LATITUDE != 0,!is.na(LONGITUDE), LONGITUDE != 0) %>% # 容差设为1e-5,可根据数据精度调整 filter(!near(LATITUDE, -78.69174, tol = 1e-5) | !near(LONGITUDE, 17.55061, tol = 1e-5))
2. 基于经纬度合理范围批量过滤
全球经纬度的有效范围是:纬度[-90, 90],经度[-180, 180]。如果知道研究区域的具体范围,还可以进一步缩小,过滤所有超出范围的异常点:
# 通用全球范围过滤 data_clean <- data_all %>% filter(!is.na(LATITUDE), LATITUDE != 0,!is.na(LONGITUDE), LONGITUDE != 0) %>% filter(between(LATITUDE, -90, 90), between(LONGITUDE, -180, 180)) # 示例:如果研究区域是北纬20-50、东经100-120,精准过滤 data_clean <- data_all %>% filter(!is.na(LATITUDE), LATITUDE != 0,!is.na(LONGITUDE), LONGITUDE != 0) %>% filter(between(LATITUDE, 20, 50), between(LONGITUDE, 100, 120))
3. 基于动物移动速度的生物逻辑过滤(更精准)
如果异常点是GPS漂移导致的不合理移动(比如瞬间移动几百公里),可以计算相邻定位点的移动速度,过滤超出动物正常移动能力的点:
library(lubridate) library(geosphere) data_clean <- data_all %>% filter(!is.na(LATITUDE), LATITUDE != 0,!is.na(LONGITUDE), LONGITUDE != 0) %>% # 按动物ID分组,按时间排序 group_by(ANIMAL_ID) %>% arrange(TIMESTAMP) %>% # 计算相邻点的距离(米)、时间差(秒)和移动速度(米/秒) mutate( distance = distHaversine(cbind(LONGITUDE, LATITUDE), cbind(lead(LONGITUDE), lead(LATITUDE))), time_diff = as.numeric(difftime(lead(TIMESTAMP), TIMESTAMP, units = "secs")), speed = distance / time_diff ) %>% # 过滤速度超过阈值的点(示例阈值50m/s,约180km/h,根据你的动物调整) filter(is.na(speed) | speed <= 50) %>% ungroup() %>% # 移除临时计算列 select(-distance, -time_diff, -speed)
内容的提问来源于stack exchange,提问作者EleMan
相关产品推荐
相关产品推荐

