求助:如何按每年动态变化的首末占用日期过滤数据库?
问题描述
现有如下结构的数据集:
Year ID Date Occupy 2010 1 10 Yes 2010 2 11 No 2010 3 12 Yes 2010 4 9 No 2010 5 15 No 2011 7 7 Yes 2011 8 9 Yes 2011 9 10 Yes 2011 11 12 No
需要实现两个操作:
- 找出每年中首个和最后一个
Occupy为Yes的日期(比如2010年是10和12,2011年是7和10) - 过滤掉日期小于该年首个占用日期、或大于最后一个占用日期的行,最终得到目标结果:
Year ID Date Occupy 2010 1 10 Yes 2010 2 11 No 2010 3 12 Yes 2011 7 7 Yes 2011 8 9 Yes 2011 9 10 Yes
曾尝试用lapply(function(x) c(min(x), max(x)))结合lubridate分组过滤,但代码运行出错或未达到预期效果。
解决方案
使用dplyr包可以高效实现需求,步骤如下:
1. 构造示例数据(若已有数据框可跳过)
df <- data.frame( Year = c(2010,2010,2010,2010,2010,2011,2011,2011,2011), ID = c(1,2,3,4,5,7,8,9,11), Date = c(10,11,12,9,15,7,9,10,12), Occupy = c("Yes","No","Yes","No","No","Yes","Yes","Yes","No") )
2. 分组计算并过滤数据
library(dplyr) result <- df %>% # 按年份分组,计算该年Occupy为Yes的最小、最大日期 group_by(Year) %>% mutate( first_occupy = min(Date[Occupy == "Yes"], na.rm = TRUE), last_occupy = max(Date[Occupy == "Yes"], na.rm = TRUE) ) %>% # 保留日期在首尾占用区间内的行 filter(Date >= first_occupy & Date <= last_occupy) %>% # 删除临时计算的辅助列 select(-first_occupy, -last_occupy) %>% ungroup() print(result)
运行后输出结果与目标一致:
# A tibble: 6 × 4 Year ID Date Occupy <dbl> <dbl> <dbl> <chr> 1 2010 1 10 Yes 2 2010 2 11 No 3 2010 3 12 Yes 4 2011 7 7 Yes 5 2011 8 9 Yes 6 2011 9 10 Yes
常见问题说明
- 之前用
lapply出错,大概率是没按年份正确分组,导致计算的是全局的最小/最大日期,而非每年单独计算 - 你的
Date是数值型(当月天数),不需要用lubridate处理,直接用数值计算即可;如果是完整日期格式,再考虑用lubridate转换后计算
内容的提问来源于stack exchange,提问作者Teresa
相关产品推荐
相关产品推荐

