如何用R的dplyr包筛选年份连续的行并生成丢弃数据集?
用dplyr实现按ID保留连续年份行并分离丢弃行
当然可以用dplyr轻松搞定这个需求!咱们可以按id分组后,通过计算相邻年份的差值来判断是否连续,同时还能一次性把保留的有效行和被丢弃的行分开。下面是完整的实现步骤:
第一步:准备输入数据
先把你提供的输入数据用R代码定义出来:
library(dplyr) # 输入数据集 df.in <- data.frame( "id"=c(1,1,1,1,1, 2,2,2,2,2,2, 3,3,3,3,3,3,3), "yr"=c(2005,2006,2007,2008,2010, 2001,2002,2003,2006,2008,2009, 2001, 2002,2003,2004,2005,2007,2009), "val"=c(5,6,7,8,10, 1,2,3,6,8,10, 1,2,3,4,5,7,9) )
第二步:标记并分离保留/丢弃行
核心思路是按id分组后,计算当前行年份与上一行年份的差值,只要差值≤1就保留(每组的第一行默认保留,因为没有上一行):
# 添加标记列,判断是否保留该行 df_processed <- df.in %>% group_by(id) %>% mutate( # 第一行标记为保留,后续行判断年份间隔是否≤1 keep = row_number() == 1 | (yr - lag(yr) <= 1) ) %>% ungroup() # 生成保留的数据集df.out df.out <- df_processed %>% filter(keep) %>% select(-keep) # 生成被丢弃的数据集df.discard df.discard <- df_processed %>% filter(!keep) %>% select(-keep)
验证结果
咱们来看看输出是否符合预期:
- 查看
df.out:
df.out #> id yr val #> 1 1 2005 5 #> 2 1 2006 6 #> 3 1 2007 7 #> 4 1 2008 8 #> 5 2 2001 1 #> 6 2 2002 2 #> 7 2 2003 3 #> 8 3 2001 1 #> 9 3 2002 2 #> 10 3 2003 3 #> 11 3 2004 4 #> 12 3 2005 5
- 查看
df.discard:
df.discard #> id yr val #> 1 1 2010 10 #> 2 2 2006 6 #> 3 2 2008 8 #> 4 2 2009 10 #> 5 3 2007 7 #> 6 3 2009 9
完全符合你想要的结果!这里关键的点是用group_by(id)确保每个ID内部单独判断年份连续性,lag(yr)获取上一行的年份值,row_number() == 1处理每组的第一行(因为没有前一行,直接保留)。
内容的提问来源于stack exchange,提问作者N08
相关产品推荐
相关产品推荐

