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
相关产品推荐
相关产品推荐

