如何计算鸟类在缓冲区的单次停留时长?含R代码报错解决
解决鸟类GPS缓冲区停留时长计算问题
一、修复当前报错
你的报错是因为group_by后使用.$引用列会调用整个数据框的列数据,而非分组后的子集,导致尺寸不匹配。直接使用列名即可,修改后的代码:
points_outside_buffer_after <- trips_with_buffer_2016_df %>% group_by(tripID) %>% filter(buffer == "no" & DateTime.x > DateTime.y) %>% slice_min(order_by = DateTime.x, n = 1)
二、处理多次进出缓冲区的情况
要捕捉同一行程内的多次进出,核心是先识别状态转换事件(进入缓冲区:从"no"→"yes";离开缓冲区:从"yes"→"no"),再将每次进入和对应的首次离开配对。
步骤1:标记状态转换
给每个GPS点标记是否为进入/离开事件:
trips_with_events <- trips_with_buffer_2016_df %>% group_by(tripID) %>% arrange(DateTime) %>% mutate(prev_buffer = lag(buffer), entry_event = ifelse(buffer == "yes" & prev_buffer == "no", TRUE, FALSE), exit_event = ifelse(buffer == "no" & prev_buffer == "yes", TRUE, FALSE)) %>% ungroup()
步骤2:提取并配对进出事件
分别提取进入、离开记录,按行程和事件序号配对,计算停留时长:
# 提取进入事件并添加序号 entry_events <- trips_with_events %>% filter(entry_event) %>% group_by(tripID) %>% mutate(entry_seq = row_number()) %>% ungroup() %>% select(tripID, entry_seq, entry_time = DateTime) # 提取离开事件并添加序号 exit_events <- trips_with_events %>% filter(exit_event) %>% group_by(tripID) %>% mutate(exit_seq = row_number()) %>% ungroup() %>% select(tripID, exit_seq, exit_time = DateTime) # 配对并计算停留时长(单位为分钟,可按需调整) stay_durations <- entry_events %>% left_join(exit_events, by = c("tripID", "entry_seq" = "exit_seq")) %>% mutate(stay_duration_min = difftime(exit_time, entry_time, units = "mins"))
步骤3:处理未离开的情况(可选)
如果存在进入缓冲区后无后续离开点的情况(如行程结束时仍在缓冲区内),用行程最后时间作为离开时间:
trip_end_times <- trips_with_events %>% group_by(tripID) %>% summarise(trip_end_time = max(DateTime)) %>% ungroup() stay_durations <- stay_durations %>% left_join(trip_end_times, by = "tripID") %>% mutate(exit_time = ifelse(is.na(exit_time), trip_end_time, exit_time), stay_duration_min = difftime(exit_time, entry_time, units = "mins")) %>% select(-trip_end_time)
注意事项
- 确保
DateTime列是POSIXct/POSIXlt格式,否则无法正确计算时长。 - 上述代码仅标记连续状态转换的首次进入和离开,符合你"每次进入后到首次离开的时长"的需求。
内容的提问来源于stack exchange,提问作者Ioannis
相关产品推荐
相关产品推荐

