You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R语言中按Herd分组合并日期相近的观测记录并统计检测次数

解决方案:按群分组并将2个月内的检测归为同一批次

你遇到的问题核心是按群(Herd)划分时间窗口,把2个月内的所有检测记录标记为同一批次,而不是按单个日期排序。原来的dense_rank(date)会把每个不同日期都算作新批次,这不符合需求。下面是两种可靠的实现方法,都基于tidyverse工具链:


方法1:基于相邻日期间隔的动态分组(更灵活)

这种方法会自动判断当前检测日期和上一个检测日期的间隔,如果超过2个月就标记为新批次,适合检测周期不严格对齐日历的场景:

library(tidyverse)
library(lubridate)

# 加载你的数据
df <- data.frame(
  animal = c("Animal1", "Animal2", "Animal3", "Animal4", "Animal5", "Animal6", "Animal1", "Animal2", "Animal3", "Animal4", "Animal5", "Animal6", "Animal7", "Animal8", "Animal9", "Animal10", "Animal11", "Animal12", "Animal7", "Animal8", "Animal9", "Animal10", "Animal11", "Animal12"),
  herd = c("Herd1","Herd1","Herd1", "Herd1","Herd1","Herd1", "Herd1","Herd1","Herd1", "Herd1","Herd1","Herd1","Herd2","Herd2", "Herd2","Herd2","Herd2","Herd2", "Herd2","Herd2", "Herd2","Herd2","Herd2","Herd2"),
  date = c("2017-01-01", "2017-01-01", "2017-01-17","2017-02-04", "2017-02-04", "2017-02-05", "2017-06-01" , "2017-06-03", "2017-07-01", "2017-06-21", "2017-06-01", "2017-06-15", "2017-02-01", "2017-02-01", "2017-02-15", "2017-02-21", "2017-03-05", "2017-03-01", "2017-07-01", "2017-07-01", "2017-07-15", "2017-07-21", "2017-08-05", "2017-08-01")
)

# 处理流程
df_with_testing <- df %>%
  # 第一步:把字符型日期转换为Date类型,方便计算
  mutate(date = ymd(date)) %>%
  # 按群分组
  group_by(herd) %>%
  # 按日期排序,确保时间顺序正确
  arrange(date) %>%
  # 标记是否为新的检测批次:第一行默认是新批次,后续如果和上一个日期差超过2个月则标记为新批次
  mutate(is_new_test = case_when(
    row_number() == 1 ~ TRUE,
    date > lag(date) + months(2) ~ TRUE,
    TRUE ~ FALSE
  )) %>%
  # 通过累加标记值,生成检测批次号
  mutate(testing = cumsum(is_new_test)) %>%
  # 恢复原数据的行顺序(因为之前按日期排序了)
  mutate(row_id = row_number()) %>%
  ungroup() %>%
  arrange(row_id) %>%
  # 移除临时辅助列
  select(-row_id, -is_new_test)

# 查看结果
print(df_with_testing)

方法2:基于日历2月窗口的固定分组(适合严格对齐周期的场景)

如果你的检测周期严格按日历每2个月为一个窗口(比如1-2月、3-4月、5-6月等),可以直接用floor_date把日期映射到窗口起始日,再用dense_rank生成批次号:

df_with_testing <- df %>%
  mutate(date = ymd(date)) %>%
  group_by(herd) %>%
  # 把日期向下取整到2个月窗口的起始日(比如1月、3月、5月...)
  mutate(window_start = floor_date(date, "2 months")) %>%
  # 对窗口起始日排序生成批次号
  mutate(testing = dense_rank(window_start)) %>%
  ungroup() %>%
  select(-window_start)

print(df_with_testing)

验证结果

两种方法都会生成你期望的testing列:

  • Herd1的1-2月检测统一标记为1,6-7月检测标记为2
  • Herd2的2-3月检测统一标记为1,7-8月检测标记为2

你可以根据实际检测周期的灵活性选择合适的方法,如果检测窗口可能跨日历月(比如1月中旬到3月中旬),方法1会更准确。

内容的提问来源于stack exchange,提问作者Gómez-Buendía A.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 15:22:35