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

在R中计算非连续行为时长(按日统计)

解决非连续筑巢行为的每日时长统计问题

问题核心

现有代码直接用max(timestamp)-min(timestamp)计算筑巢时长,会把整个观测时段全部计入,但实际筑巢行为是非连续的,必须先识别每一段连续的筑巢区间,再累加各区间的时长才能得到准确结果。

解决方案

我们需要先标记筑巢状态,再识别连续的筑巢区间,最后按日期(及个体)累加各区间的时长。以下是基于tidyverse的实现方案:

步骤1:数据预处理与状态标记

先确保时间格式正确,同时给每条记录标记是否属于筑巢行为:

library(tidyverse)

data_tibble <- data_tibble %>%
  mutate(timestamp = as.POSIXct(timestamp)) %>%
  # 标记当前记录是否为筑巢行为(距离巢穴≤30米)
  mutate(is_nesting = Dist <= 30)

步骤2:识别连续筑巢区间并计算总时长

使用rleid(来自data.table)给连续的筑巢/非筑巢记录分配唯一ID,以此区分不同的行为区间,再累加每个筑巢区间的时长:

library(data.table)

nest_duration_perday <- data_tibble %>%
  # 按个体+日期分组,确保不同个体、不同日期的统计独立
  group_by(bird_ID, date) %>%
  # 生成连续行为区间的ID:连续的相同is_nesting状态会得到同一个ID
  mutate(interval_id = rleid(is_nesting)) %>%
  # 只保留筑巢行为的区间
  filter(is_nesting) %>%
  # 按区间分组,计算单个筑巢区间的时长
  group_by(bird_ID, date, interval_id) %>%
  summarise(interval_duration = max(timestamp) - min(timestamp), .groups = "drop_last") %>%
  # 按日期+个体累加所有筑巢区间的总时长
  summarise(total_nesting_duration = sum(interval_duration))

纯dplyr替代方案(无需依赖data.table)

如果不想引入data.table,可以用lag函数手动判断状态变化,生成区间ID:

nest_duration_perday <- data_tibble %>%
  mutate(timestamp = as.POSIXct(timestamp),
         is_nesting = Dist <= 30) %>%
  group_by(bird_ID, date) %>%
  # 判断当前记录与上一条的筑巢状态是否变化,生成切换标记
  mutate(status_change = is_nesting != lag(is_nesting, default = !is_nesting[1]),
         # 累加切换标记生成区间ID
         interval_id = cumsum(status_change)) %>%
  filter(is_nesting) %>%
  group_by(bird_ID, date, interval_id) %>%
  summarise(interval_duration = max(timestamp) - min(timestamp), .groups = "drop_last") %>%
  summarise(total_nesting_duration = sum(interval_duration))

示例数据的输出结果

运行上述代码后,针对你的示例数据,会得到符合实际的筑巢总时长:

#> # A tibble: 1 × 3
#> # Groups:   bird_ID [1]
#>   bird_ID date       total_nesting_duration
#>   <chr>   <chr>      <drtn>                
#> 1 048T    2022-06-04 2.500278 hours

(注:示例数据中连续筑巢的区间是2022-06-04 10:49:36到2022-06-04 13:19:39,时长约2.5小时,完全匹配数据中的实际筑巢时段)

补充说明

  • 代码中加入bird_ID分组,是因为不同个体的巢穴位置独立,需要分开统计;如果你的数据集仅涉及单个个体,可以去掉该分组。
  • 最终结果按bird_ID和date汇总,确保每日每个个体的筑巢时长统计准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 11:35:23