You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R中按个体鸟类计算定位时间差结果不符预期的问题

按个体计算海鸟追踪记录时间差的问题

使用track2KBA包的海鸟追踪数据集,想要按track_id(个体鸟类)分组,计算每条定位记录与同个体上一条记录的时间差。运行脚本后得到的结果不符合预期,误以为第一条记录(track_id=69303,11:01:54)与同个体下一条记录的时间差应为6秒,但实际输出未得到该结果。

错误输出示例

track_id date_gmt   time_gmt longitude latitude lon_colony lat_colony datetime            difference
      <int> <chr>      <chr>        <dbl>    <dbl>      <dbl>      <dbl> <dttm>              <drtn>    
 1    69303 2012-07-21 11:01:54     -5.73    -16.0      -5.73      -16.0 2012-07-21 11:01:54  NA secs  
 2    69302 2012-07-21 11:02:00     -5.73    -16.0      -5.73      -16.0 2012-07-21 11:02:00  NA secs  
 3    69303 2012-07-21 11:03:33     -5.73    -16.0      -5.73      -16.0 2012-07-21 11:03:33  99 secs  
 4    69302 2012-07-21 11:03:42     -5.73    -16.0      -5.73      -16.0 2012-07-21 11:03:42 102 secs  
 5    69303 2012-07-21 11:05:13     -5.73    -16.0      -5.73      -16.0 2012-07-21 11:05:13 100 secs  
 6    69302 2012-07-21 11:05:26     -5.73    -16.0      -5.73      -16.0 2012-07-21 11:05:26 104 secs  

用户代码

library(track2KBA)
library(tidyverse)
library(lubridate)

boobies$datetime <-
 (paste(boobies$date_gmt, boobies$time_gmt))

boobies <- boobies %>%
  mutate(datetime = lubridate::ymd_hms(datetime)) %>%
  group_by(track_id) %>%
  arrange(datetime) %>%
  mutate(difference = datetime - lag(datetime))

示例数据

boobies <- structure(list(track_id = c(69303L, 69302L, 69303L, 69302L, 69303L, 
69302L), date_gmt = c("2012-07-21", "2012-07-21", "2012-07-21", 
"2012-07-21", "2012-07-21", "2012-07-21"), time_gmt = c("11:01:54", 
"11:02:00", "11:03:33", "11:03:42", "11:05:13", "11:05:26"), 
    longitude = c(-5.72769, -5.72639, -5.72769, -5.72635, -5.72769, 
    -5.72639), latitude = c(-16.00749, -16.00713, -16.00749, 
    -16.00723, -16.00749, -16.0071), lon_colony = c(-5.73, -5.73, 
    -5.73, -5.73, -5.73, -5.73), lat_colony = c(-16.01, -16.01, 
    -16.01, -16.01, -16.01, -16.01), datetime = c("2012-07-21 11:01:54", 
    "2012-07-21 11:02:00", "2012-07-21 11:03:33", "2012-07-21 11:03:42", 
    "2012-07-21 11:05:13", "2012-07-21 11:05:26")), .internal.selfref = <pointer: (nil)>, row.names = c(NA, 6L), class = c("data.table", "data.frame"))

解决方案

你的代码逻辑其实是正确的,问题出在对数据的误解:

  • 第一条记录(行1)的track_id是69303,下一条同个体记录是行3(11:03:33),两者时间差为99秒,这和输出结果一致,是正确的。
  • 你提到的6秒是行1和行2的时间差,但这两条记录属于不同个体(行2的track_id是69302),所以不会被计算为同个体的时间差。

如果希望输出结果按个体+时间顺序排列,让同个体的记录连续显示,方便查看,可以在管道最后加上ungroup() %>% arrange(track_id, datetime),修改后的代码如下:

library(track2KBA)
library(tidyverse)
library(lubridate)

boobies <- boobies %>%
  mutate(datetime = lubridate::ymd_hms(paste(date_gmt, time_gmt))) %>%
  group_by(track_id) %>%
  arrange(datetime) %>%
  mutate(difference = datetime - lag(datetime)) %>%
  ungroup() %>%
  arrange(track_id, datetime)

运行后输出会按个体分组,同个体的记录按时间排序,结果更直观:

track_id date_gmt   time_gmt longitude latitude lon_colony lat_colony datetime            difference
      <int> <chr>      <chr>        <dbl>    <dbl>      <dbl>      <dbl> <dttm>              <drtn>    
 1    69302 2012-07-21 11:02:00     -5.73    -16.0      -5.73      -16.0 2012-07-21 11:02:00  NA secs  
 2    69302 2012-07-21 11:03:42     -5.73    -16.0      -5.73      -16.0 2012-07-21 11:03:42 102 secs  
 3    69302 2012-07-21 11:05:26     -5.73    -16.0      -5.73      -16.0 2012-07-21 11:05:26 104 secs  
 4    69303 2012-07-21 11:01:54     -5.73    -16.0      -5.73      -16.0 2012-07-21 11:01:54  NA secs  
 5    69303 2012-07-21 11:03:33     -5.73    -16.0      -5.73      -16.0 2012-07-21 11:03:33  99 secs  
 6    69303 2012-07-21 11:05:13     -5.73    -16.0      -5.73      -16.0 2012-07-21 11:05:13 100 secs  

另外,代码里可以直接在mutate中生成datetime,不需要单独先给boobies$datetime赋值,这样更符合tidyverse的风格。


内容的提问来源于stack exchange,提问作者adkane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 05:12:02