如何基于另一数据框的ID与Year组合筛选目标数据框行
问题描述
我有两个数据框df1和df2,二者都包含四列,其中ID、Year、Week列名相同,另有一列列名不同:
df1数据:
ID Year Oxygen Week ---- ------ ------- ------- 1 2004 18 1 1 2005 17 1 2 2006 17 1 2 2007 18 1 3 2008 19 1 3 2010 20 1 3 2010 20 1 4 2012 16 1 5 2013 18 1 6 2014 18 1
df2数据:
ID Year Kg Week ---- ------ ----- ------- 1 2004 20 1 1 2005 35 2 2 2006 30 2 3 2007 15 1 3 2008 70 2 4 2009 40 1 5 2013 55 1 6 2012 40 1 6 2014 10 2 7 2013 15 1
我需要生成新数据框df3,仅保留df1中ID和Year的组合同时存在于df2中的行,无需考虑Week列的取值。比如df1第二行的ID和Year组合在df2中存在,但Week取值不同,仍需保留。
我已知单列筛选的方法:
df3 <- subset(df1, ID %in% df2$ID)
也知道无Week列时的解决方案:
df3 <- df1 %>% inner_join(df2)
但不知如何同时基于ID和Year筛选且排除Week的影响,最终需得到仅含df1列的目标数据框:
期望的df3结果:
ID Year Oxygen Week ---- ------ ------- ------- 1 2004 18 1 1 2005 17 1 2 2006 17 1 3 2008 19 1 4 2012 16 1 5 2013 18 1 6 2014 18 1
解决方案
以下是几种高效的实现方式:
方法1:dplyr指定连接键筛选
利用inner_join时仅按ID和Year连接,同时只保留df1的列:
library(dplyr) df3 <- df1 %>% inner_join(df2 %>% select(ID, Year), by = c("ID", "Year"))
- 先从
df2提取仅包含ID和Year的子集,避免多余列干扰 - 通过
by = c("ID", "Year")明确连接键,忽略Week列 - 结果自动保留
df1的所有列,完全符合需求
方法2:基础R结合组合判断
不用dplyr的话,可通过interaction生成ID+Year的唯一组合来筛选:
# 生成df2中ID+Year的唯一组合标识 df2_combinations <- interaction(df2$ID, df2$Year) # 筛选df1中组合存在于df2的行 df3 <- subset(df1, interaction(ID, Year) %in% df2_combinations)
interaction()将ID和Year拼接成唯一字符串,用于组合匹配- 利用
%in%快速判断组合是否存在,实现精准筛选
方法3:data.table高效处理(适合大数据)
如果数据量较大,用data.table的性能更优:
library(data.table) setDT(df1) setDT(df2) # 指定连接键,仅保留匹配行并保留df1原列 df3 <- df1[df2[, .(ID, Year)], on = .(ID, Year), nomatch = 0]
内容的提问来源于stack exchange,提问作者Erik Christensen
相关产品推荐
相关产品推荐

