R大型动物追踪数据集:计算1小时窗内的跨动物观测点地理距离
1小时时间窗口约束下的动物观测点距离计算方案
核心逻辑调整
原有代码基于无边界的近邻时间匹配计算跨动物距离,本次适配仅在原有匹配逻辑上增加时间阈值限制,未改动其他流程:
- 保留「对每个观测点,匹配其他动物时间上最接近的观测记录」的核心行为
- 新增1小时(3600秒)的匹配窗口约束:若匹配到的最近观测与当前观测的时间差绝对值超过3600秒,匹配结果自动设为NA
- 无其他动物观测落在前后1小时范围内时,对应距离值直接输出NA
完整适配代码
library( data.table ) library( sf ) library( geosphere ) library( tidyverse ) # 读取自有追踪数据 DT <- data.table::fread("你的数据文件路径.csv") # 构建统一格式的时间字段 DT[, datetime := as.POSIXct( paste(Date, Time ), format = "%Y-%m-%d %H:%M" ) ] # 坐标投影转换:从UTM 32736坐标系转WGS84经纬度 DT[ , c("lon", "lat") := DT %>% sf::st_as_sf( coords = c("GPS.S", "GPS.E"), crs = 32736 ) %>% sf::st_transform( 4326 ) %>% sf::st_coordinates() %>% data.table::as.data.table() ][] # 按动物ID拆分独立数据集列表 L <- split( DT, by = "ID" ) # 跨动物观测点时间匹配环节(核心改动位置) lapply( L, function(x) { lapply( L, function(y) { x[, unique(y$ID) := y[x, x.rowid, roll = "nearest", tol = 3600, # 1小时窗口,单位为秒 on = .(datetime)] ] }) }) # 合并所有匹配结果 CD <- data.table::rbindlist( L, fill= T ) # 转换为长表格式,为后续关联坐标做准备 CD.melt <- data.table::melt(CD, measure.vars = patterns("Animal"), variable.name = "ID2", variable.factor = FALSE, value.name = "rowid2" ) # 关联配对动物的经纬度坐标 CD.melt[ CD, `:=`( lon2 = i.lon, lat2 = i.lat ), on = .(rowid2 = rowid) ][] # 计算两点间球面距离 CD.melt <- CD.melt %>% dplyr::mutate( distance = purrr::pmap_dbl( list( a = lon, b = lat, x = lon2, y = lat2 ), ~ round( geosphere::distHaversine( c(..1, ..2), c(..3, ..4) ) ) ) ) # 转换为最终宽表输出 dcast( CD.melt, rowid + ID + GPS.E + GPS.S + Date + Time ~ ID2, value.var = "distance" )
关键配置说明
- 窗口大小可灵活调整:仅需修改
tol参数的数值即可自定义允许的最大时间差(单位为秒,如30分钟窗口设为tol=1800) - 兼容任意数量的追踪动物:无需逐次修改匹配规则,自动适配不同ID的跨动物匹配
- 保留原代码的计算性能:基于data.table的高效滚动连接,不会因增加窗口约束明显提升运行时长
样本数据匹配效果验证
基于提供的3个动物的观测样本,典型匹配结果如下:
- 记录rowid=1(Animal1,2017-01-01 06:19):与Animal2的最近观测时间差71分钟、与Animal3的最近观测时间差160分钟,均超出1小时窗口,对应距离值输出NA
- 记录rowid=2(Animal1,2017-01-01 08:45):与Animal3的最近观测时间差14分钟,在1小时窗口内,正常计算两点距离;与Animal2的最近观测时间差75分钟,超出窗口,对应距离输出NA
内容的提问来源于stack exchange,提问作者Bett21
相关产品推荐
相关产品推荐

