如何在R语言中为奶牛数据集计算泌乳天数(DIM)列
解决奶牛泌乳天数(DIM)计算问题
需求回顾
基于包含奶牛ID、日期、事件的数据集,生成DIM列规则如下:
- 产犊(
calved)当日标记为"1",后续日期为距产犊日的天数 - 干奶(
dry-off)当日及干奶至下次产犊前的所有日期标记为"0"
解决方案代码
使用dplyr按奶牛ID和泌乳周期分组处理,完整代码如下:
library(dplyr) # 原始数据集构建 ID <- c("A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B") date <- c("2022-01-01", "2022-01-05", "2022-01-06", "2022-01-07", "2022-01-10", "2022-01-12", "2022-01-13", "2022-01-16", "2022-01-17", "2022-01-18", "2022-02-01", "2022-02-05", "2022-02-06", "2022-02-07", "2022-02-10", "2022-02-12", "2022-02-13", "2022-02-16", "2022-02-17", "2022-02-18") event <- c("calved", "NA", "NA", "NA", "dry-off", "NA", "NA", "calved", "NA", "NA", "calved", "NA", "NA", "NA", "dry-off", "NA", "calved", "NA", "NA", "NA") df <- data.frame(ID, date, event) df$date <- as.Date(df$date) # 计算DIM列 result <- df %>% group_by(ID) %>% # 标记每个泌乳周期:每出现一次calved,周期数+1 mutate(lactation_cycle = cumsum(event == "calved")) %>% group_by(ID, lactation_cycle) %>% # 获取当前周期的产犊日期 mutate(calve_date = first(date[event == "calved"]), # 计算初始泌乳天数:产犊日为1,后续为日期差+1 temp_dim = as.integer(date - calve_date) + 1, # 获取当前周期的干奶日期(无干奶则为NA) dry_off_date = ifelse(any(event == "dry-off"), max(date[event == "dry-off"]), NA_Date_), # 按规则生成最终DIM DIM = case_when( event == "dry-off" | date >= dry_off_date ~ "0", TRUE ~ as.character(temp_dim) )) %>% # 移除辅助列 select(-lactation_cycle, -calve_date, -temp_dim, -dry_off_date) %>% ungroup() # 验证结果与目标数据集匹配 what_I_want <- data.frame(ID, date, event, DIM = c("1", "5", "6", "7", "0", "0", "0", "1", "2", "3", "1", "5", "6", "7", "0", "0", "1", "4", "5", "6")) all.equal(result, what_I_want) # 输出TRUE表示结果一致
代码逻辑说明
- 分组标记泌乳周期:按奶牛ID分组后,用
cumsum(event == "calved")为每个泌乳周期分配唯一编号,确保每个产犊事件开启新的周期。 - 获取周期关键日期:在每个泌乳周期内,提取产犊日期和干奶日期(如果存在)。
- 计算初始泌乳天数:通过日期差加1得到初始DIM值(产犊日为1)。
- 调整干奶期DIM:将干奶日及之后的日期统一设为
"0",覆盖初始计算值。 - 清理输出:移除中间辅助列,得到符合需求的最终数据集。
内容的提问来源于stack exchange,提问作者AlHu
相关产品推荐
相关产品推荐

