基于相机部署日期将熊检测数据转换为14天二进制检测历史的R代码修正需求
基于相机部署日期将熊检测数据转换为14天二进制检测历史的R代码修正需求
问题背景
你手头有一份熊检测的数据集,想要生成14天的二进制检测历史:
- 每一行对应一个相机点位(
plot) - 生成
day1到day14共14列,以相机的部署日期actual_date_out为第1天 - 14天内,某天有熊检测记录(对应
start_time的日期)就标记为1,无记录则标记为0 - 每个相机只有一个部署日期,但同一天可能有多条检测记录,这类情况只需要记一次1
你现有的代码没能正确匹配start_time日期来标记1,反而错误地把第一列设为1、后续全为0,需要修正。
修正后的完整代码
library(tidyverse) # 读取数据(可替换为你的文件路径,或保留file.choose()手动选择) d <- read_csv(file.choose()) # 统一转换所有日期列的格式 d <- d %>% mutate( actual_date_out = as.Date(actual_date_out, format = "%m/%d/%Y"), retrieval_date = as.Date(retrieval_date, format = "%m/%d/%Y"), start_time = as.Date(start_time, format = "%m/%d/%Y") ) # 步骤1:按相机分组,生成每个相机的14天日期序列(从部署日开始) d_days <- d %>% group_by(plot) %>% reframe( actual_date_out = first(actual_date_out), detection_day = seq.Date(first(actual_date_out), first(actual_date_out) + 13, by = "day"), pres_abs = 0, # 先默认所有天数为无检测(0) actual_lat = first(actual_lat), actual_long = first(actual_long) ) %>% ungroup() # 步骤2:提取每个相机的有效检测日期(去重,同一天只保留一条有效记录) d_detections <- d %>% group_by(plot, start_time) %>% summarise(pres_abs = 1, .groups = "drop") # 步骤3:合并日期序列与检测记录,更新有检测的日期标记为1 d_combined <- d_days %>% left_join(d_detections, by = c("plot", "detection_day" = "start_time")) %>% # 用coalesce函数:有检测记录的用1,无记录的保留原默认的0 mutate(pres_abs = coalesce(pres_abs.y, pres_abs.x)) %>% select(-pres_abs.x, -pres_abs.y) # 步骤4:转换为宽格式,生成day1到day14的列 d_final <- d_combined %>% group_by(plot) %>% arrange(detection_day) %>% mutate(day = paste0("day_", row_number())) %>% ungroup() %>% pivot_wider( id_cols = c(plot, actual_lat, actual_long, actual_date_out), names_from = day, values_from = pres_abs ) # 查看最终结果 head(d_final)
代码关键逻辑解释
- 日期格式统一:先把所有日期列转换成标准
Date类型,避免后续日期匹配出错 - 生成14天基准序列:按相机分组,从部署日开始生成连续14天的日期,先默认所有天数为0(无检测)
- 提取有效检测日期:对每个相机的
start_time去重,确保同一天的多条检测记录只标记一次1 - 合并更新标记:用左连接把检测日期和14天基准序列匹配,有检测的日期替换为1,无检测的保留0
- 转宽格式输出:把长格式的日期序列转换成
day1到day14的宽格式,完全符合你需要的二进制检测历史结构
这样处理后,就能准确根据start_time的日期来标记14天检测历史中的1和0,每个相机的部署日为第1天,后续天数依次对应。
内容来源于stack exchange
相关产品推荐
相关产品推荐

