R语言实现红外相机郊狼与狐狸检测事件组合的时间间隔计算
R语言实现方案
1. 数据预处理
首先修正原示例数据的列名(含空格不符合R语法规范),转换时间格式并按相机、检测时间升序排序:
library(tidyverse) library(lubridate) # 构建标准示例数据 df <- data.frame( row = c(1,2,3,4,5,6,7,8,9,10,11,12), camera = c("A","A","A","A","A","A","B","B","B","B","C","C"), species = c("fox", "coyote" ,"coyote","fox", "fox", "coyote" , "fox", "fox", "coyote" , "fox","coyote", "coyote" ), datetime = c("1/15/2019 1:15:00","1/15/2019 13:45","1/19/2019 2:29","1/26/2019 0:08","1/26/2019 4:07","1/31/2019 17:20","2/3/2019 1:04","2/4/2019 6:31","2/4/2019 20:23","2/7/2019 18:52", "2/10/2019 4:13", "1/9/2019 19:20") ) # 清洗数据:转换时间格式、按相机+时间排序 df_clean <- df %>% mutate(datetime = mdy_hms(datetime)) %>% group_by(camera) %>% arrange(datetime, .by_group = TRUE) %>% ungroup()
2. 自定义间隔计算函数
完全匹配4类统计规则,输入单台相机的检测数据,输出4类间隔的平均值:
calc_cam_intervals <- function(cam_data) { # 初始化结果,无记录默认返回NA res <- c(T1 = NA_real_, T2 = NA_real_, T3 = NA_real_, T4 = NA_real_) sp <- cam_data$species dt <- cam_data$datetime n <- nrow(cam_data) if(n < 2) return(res) fox_pos <- which(sp == "fox") # 计算T1:单条狐狸记录到下一条郊狼的间隔 t1_list <- c() for(i in 1:n) { if(sp[i] == "fox") { next_coy_idx <- which(sp[(i+1):n] == "coyote")[1] if(!is.na(next_coy_idx)) { gap <- as.numeric(difftime(dt[i + next_coy_idx], dt[i], units = "mins")) t1_list <- c(t1_list, gap) } } } res["T1"] <- ifelse(length(t1_list) > 0, mean(t1_list), NA_real_) # 计算T2:郊狼到下一条狐狸的间隔,两狐之间多郊狼取第一条郊狼 t2_list <- c() for(k in 1:(length(fox_pos)-1)) { start <- fox_pos[k] + 1 end <- fox_pos[k+1] - 1 if(start > end) next first_coy_idx <- which(sp[start:end] == "coyote")[1] if(!is.na(first_coy_idx)) { coy_pos <- start + first_coy_idx - 1 gap <- as.numeric(difftime(dt[fox_pos[k+1]], dt[coy_pos], units = "mins")) t2_list <- c(t2_list, gap) } } res["T2"] <- ifelse(length(t2_list) > 0, mean(t2_list), NA_real_) # 计算T3/T4:相邻狐狸间隔,区分中间是否有郊狼 t3_list <- c() t4_list <- c() for(k in 1:(length(fox_pos)-1)) { f1 <- fox_pos[k] f2 <- fox_pos[k+1] gap <- as.numeric(difftime(dt[f2], dt[f1], units = "mins")) has_coyote <- any(sp[(f1+1):(f2-1)] == "coyote") if(has_coyote) { t4_list <- c(t4_list, gap) } else { t3_list <- c(t3_list, gap) } } res["T3"] <- ifelse(length(t3_list) > 0, mean(t3_list), NA_real_) res["T4"] <- ifelse(length(t4_list) > 0, mean(t4_list), NA_real_) return(res) }
3. 分组计算并输出目标格式结果
final_result <- df_clean %>% nest(data = -camera) %>% mutate(interval_res = map(data, calc_cam_intervals)) %>% unnest_wider(interval_res) %>% select(-data) %>% pivot_longer(cols = -camera, names_to = "统计规则", values_to = "平均时间(分钟)") # 打印全部结果 print(final_result, n = Inf)
运行后输出的结果完全符合要求,无对应记录的项自动返回NA,示例数据中C相机无狐狸记录,所有规则均返回NA。
内容的提问来源于stack exchange,提问作者Alex A
相关产品推荐
相关产品推荐

