R语言筛选满足全部条件记录异常:示例有效真实数据无效
问题分析与解决:筛选包含所有指定年份的站点记录
问题背景
需求是从包含site_code和season(年份)的数据集中,提取同时包含2019、2020、2021、2022四个年份的站点记录。用户通过简化示例reprex_1验证逻辑时结果符合预期,但将同一逻辑应用到真实数据reprex_2时,代码返回了所有站点,而非仅符合条件的4-096-01,且仅当条件长度为1时筛选正常,长度为4时失效。
错误原因
核心问题是逻辑判断方向搞反了:
- 原代码中
filter(all(season %in% season_criteria))的逻辑是:该站点的所有年份都属于指定年份范围,只要站点的年份没超出2019-2022,就会被保留。比如站点4-001-01只有2019和2020,这两个年份都在指定范围内,所以会被错误保留。 - 而实际需求是:指定的所有年份都必须在该站点的年份列表中,也就是站点必须覆盖全部四个目标年份。
修正方案
将判断逻辑反转,改为检查指定的所有年份是否都存在于当前站点的年份集合中,使用all(season_criteria %in% season);如果要求站点只能包含这四个年份(不能有其他额外年份),则可以用setequal(unique(season), season_criteria)。
修正后的代码
library(dplyr) # REPREX_2: 修正后的代码 ---------------------------- season_criteria <- 2019:2022 df4reprex_2 <- data.frame( site_code = c(rep("4-001-01", 9), # 2019 x 2, 2020 x 7 rep("4-005-01", 1), # 2019 x 1 rep("4-060-21", 6), # 2019 x 4, 2020 x 2 rep("4-060-22", 6), # 2019 x 4, 2020 x 2 rep("4-096-01", 11), # 2019 x 2, 2020 x 3, 2021 x 3, 2022 x 3 rep("4-096-04", 2)), # 2022 x 2 season = c(rep(2019, 2), rep(2020, 7), # 4-001-01 rep(2019, 1), # 4-005-01 rep(2019, 4), rep(2020, 2), # 4-060-21 rep(2019, 4), rep(2020, 2), # 4-060-22 rep(2019, 2), rep(2020, 3), rep(2021, 3), rep(2022, 3), # 4-096-01; 符合要求 rep(2022, 2)) # 4-096-04 ) # 修正filter逻辑:检查所有目标年份是否都在当前站点的年份中 df4reprex_2 %>% group_by(site_code) %>% filter(all(season_criteria %in% season)) %>% ungroup() %>% table() # 现在仅返回符合条件的site_code "4-096-01",符合预期
补充说明
如果需要同时满足“仅包含指定年份,无额外年份”,可以将filter条件替换为:
filter(setequal(unique(season), season_criteria))
内容的提问来源于stack exchange,提问作者Sam Lin
相关产品推荐
相关产品推荐

