如何在R语言中计算动物静止行为片段的序号及时长
用dplyr处理动物静止片段的时序数据
我之前处理过类似的行为学时序数据,用dplyr结合data.table的rleid函数就能轻松搞定你的需求,下面分两种场景给你具体实现方案:
场景1:保留所有行(非静止行填充NA)
首先要确保你的数据是按time列时序排序的,之后我们可以通过识别连续的isImmobile = TRUE片段来生成序号和时长:
library(dplyr) library(data.table) # 借助它的rleid函数识别连续分组 # 假设你的原始数据框名为df result_full <- df %>% arrange(time) %>% # 先按时间排序,保证时序逻辑正确 mutate( # 生成连续片段的临时ID:仅isImmobile为TRUE的行分配组ID ep_temp = ifelse(isImmobile, rleid(isImmobile), NA_integer_) ) %>% group_by(ep_temp) %>% mutate( # 计算每个静止片段的总时长 Ep_Duration = ifelse(isImmobile, n(), NA_integer_), # 给静止片段分配从1开始的连续序号 Ep_number = ifelse(isImmobile, dense_rank(ep_temp), NA_integer_) ) %>% ungroup() %>% select(-ep_temp) # 移除临时辅助列
运行后就能得到你期望的输出:非静止行的Ep_number和Ep_Duration填充为NA,同一静止片段的所有行共享同一个序号和总时长。
场景2:直接剔除非静止行
如果不需要保留isImmobile = FALSE的行,可以简化流程,直接过滤后处理:
result_filtered <- df %>% arrange(time) %>% filter(isImmobile) %>% # 只保留静止状态的行 mutate(ep_temp = rleid(isImmobile)) %>% group_by(ep_temp) %>% mutate( Ep_number = dense_rank(ep_temp), Ep_Duration = n() ) %>% ungroup() %>% select(-ep_temp)
这样得到的结果仅包含静止状态的行,每个片段对应唯一的序号和总时长。
补充说明
rleid(isImmobile)的核心作用是给连续相同的isImmobile值分配递增ID,连续的TRUE会得到同一个ID,切换为FALSE时ID自动变化,完美匹配我们识别连续静止片段的需求。- 如果不想依赖
data.table,也可以用dplyr原生函数实现类似rleid的分组逻辑:
原理是通过比较当前行与上一行的mutate(ep_temp = cumsum(isImmobile != lag(isImmobile, default = !isImmobile[1])))isImmobile值,当状态发生变化时累加计数,同样能生成连续组的ID。
内容的提问来源于stack exchange,提问作者Alja
相关产品推荐
相关产品推荐

