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

R语言数据筛选:按站点年份取最大值及前后日期观测值

问题

我有一个包含450条观测记录的数据集,变量包括date、year、site、number。需求是:

  • 先按site和year筛选出number取值最大的观测记录
  • 再选取该记录对应日期的前后日期的观测数据

目前已通过dplyr::group_by(site,year) %>% slice_max(n=1, number)完成第一步,后续操作遇到瓶颈,寻求解决方法。

数据集示例代码:

df <- data.frame(
  year = c(rep(2029, 10), rep(2020, 10), rep(2021, 10)),
  date = c(seq(as.Date("2029-01-01"), as.Date("2029-01-10"), by = "day"),
            seq(as.Date("2020-01-01"), as.Date("2020-01-10"), by = "day"),
            seq(as.Date("2021-01-01"), as.Date("2021-01-10"), by = "day")),
  site = rep(c("Site A", "Site B", "Site C"), each = 10, times = 3),
  number = sample(1:100, 30, replace = TRUE))

解决方案

方法一:连接基准表筛选

先提取每个site+year组中number最大的记录,生成包含目标日期前后范围的基准表,再和原数据集连接筛选符合条件的记录:

library(dplyr)

# 生成基准表:每个site+year组的最大number记录,以及目标日期的前后1天范围
max_date_ranges <- df %>%
  group_by(site, year) %>%
  slice_max(n = 1, order_by = number) %>%
  ungroup() %>%
  mutate(date_low = date - 1, date_high = date + 1) %>%
  select(site, year, date_low, date_high)

# 连接原数据并筛选日期范围内的记录
final_data <- df %>%
  inner_join(max_date_ranges, by = c("site", "year")) %>%
  filter(date >= date_low & date <= date_high) %>%
  select(-date_low, -date_high)

方法二:窗口函数直接标记筛选

在原数据集上用窗口函数标记出每组的目标日期,直接筛选符合范围的记录,无需额外连接:

library(dplyr)

final_data <- df %>%
  group_by(site, year) %>%
  # 获取当前组中number最大的日期
  mutate(target_date = date[which.max(number)]) %>%
  # 筛选日期在目标日期前后1天内的记录
  filter(date >= target_date - 1 & date <= target_date + 1) %>%
  select(-target_date) %>%
  ungroup()

处理并列最大值的情况

如果同一个site+year组里存在多条number同为最大值的记录,只需稍作调整:

  • 将slice_max(n=1)改为slice_max(n=Inf)(方法一)
  • 将date[which.max(number)]改为date[number == max(number)],同时调整筛选条件为:
    filter(date %in% (target_date - 1) | date %in% target_date | date %in% (target_date + 1))
    

内容的提问来源于stack exchange,提问作者CMai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 23:27:28