时间序列截面数据集筛选:保留TRUE值及其前4个FALSE值
时间序列截面数据筛选:保留TRUE值及其前4个FALSE值
我有一个时间序列截面数据集,value列中的TRUE值出现在若干FALSE值之后,需要筛选数据,保留所有TRUE值及其对应的前4个FALSE值。以下是示例输入数据和期望输出数据:
示例输入数据
df = tibble(country = c("A","A","A","A","A","A","A", "B","B","B","B","B","B","B", "C", "C", "C", "C", "C", "C", "C", "D", "D", "D", "D", "D", "D", "D"), year = c("2010", "2011", "2012", "2013", "2014","2015", "2016", "2010", "2011", "2012", "2013", "2014","2015", "2016", "2010", "2011", "2012", "2013", "2014","2015", "2016", "2010", "2011", "2012", "2013", "2014","2015", "2016"), value = c(TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE))
期望输出数据
outcome = tibble(country = c("A","A","A","A","A", "B","B","B","B","B", "C", "C", "C", "C", "C", "D", "D", "D", "D", "D"), year = c("2011", "2012", "2013", "2014","2015", "2011", "2012", "2013", "2014","2015", "2011", "2012", "2013", "2014","2015", "2011", "2012", "2013", "2014","2015"), value = c(FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE))
解决方案
使用dplyr和purrr包可以高效实现需求,核心思路是按国家分组后,定位每个TRUE值的位置,再筛选出该位置及前4行的记录:
library(dplyr) library(purrr) df_filtered <- df %>% group_by(country) %>% # 为每组内的行添加序号 mutate(row_num = row_number()) %>% # 筛选行号落在任意TRUE值位置前4到自身范围内的记录 filter( map_lgl(row_num, ~ any(between(.x, (which(value == TRUE) - 4), which(value == TRUE)))) ) %>% # 移除辅助列 select(-row_num) %>% ungroup() # 验证结果是否与期望输出一致 all.equal(df_filtered, outcome)
代码说明
- 分组:按
country分组,确保每个国家的时间序列单独处理 - 添加行号:用
row_number()生成每组内的行序号,方便定位位置 - 筛选逻辑:对每一行的行号,检查是否落在任意一个TRUE值位置的前4位到该位置之间(包含两端)
- 清理:移除辅助的行号列,取消分组
如果你的数据中存在TRUE值前面不足4个FALSE的情况,该代码会自动保留从起始行到TRUE值的所有记录,无需额外调整。
内容的提问来源于stack exchange,提问作者Alper Yılmaz
相关产品推荐
相关产品推荐

