【问题标题】:How to compare two data frames and drop those rows appearing in 2nd data frame "knock out list" using dplyr()? [duplicate]如何使用 dplyr() 比较两个数据帧并删除出现在第二个数据帧“淘汰列表”中的那些行? [复制]
【发布时间】:2026-01-17 11:45:02
【问题描述】:

如果可能的话,我想坚持dplyr()(我是我的忠实粉丝),或者如果解决方案很简单,base R 也可以。

假设您有两个数据框,如下所示。我想创建一个新的数据框来比较两者(df1df2),并且只显示来自df1 的完整行,其ID 没有出现在df2 中显示的ID 中。 df2 充当“淘汰”列表。这将如何实现?

df1 <- data.frame(
  ID = c(1,2,3,4,5),
  Value = c(10,20,30,40,50)
)

df2 <- data.frame(
  ID = c(6,7,8,1,2),
  Value = c(60,70,80,10,20)
)

新的数据框,称为df3,在应用df2“knock outs”后,在 R Studio 控制台中运行时将如下所示:

  ID Value
1  3    30
2  4    40
3  5    50

ID 的 1 和 2 被淘汰了,因为它们同时出现在 df1df2 中。

【问题讨论】:

    标签: r dataframe dplyr


    【解决方案1】:

    这可以通过anti_join 实现:

    dplyr::anti_join(df1, df2, by = "ID")
    #>   ID Value
    #> 1  3    30
    #> 2  4    40
    #> 3  5    50
    

    【讨论】:

    • 我知道 dplyr() 会为此提供优雅的功能!我不会忘记像“anti_join”这样的名字!快速提问:除了表示这是一个 dplyr 函数之外,将“dplyr::”放在开头是否有任何帮助?
    • 视情况而定。 (: 在这里我只是为了简洁而使用它。我个人使用:: 表示法在我只需要一个包中的一个或两个函数或者当我在脚本中只需要一个函数或者当我在我自己的内部使用函数时包或当我想避免名称冲突时。通常在使用:: 时,性能会有所下降。但是,附加整个包也涉及一些一次性开销。因此需要权衡。
    【解决方案2】:

    正如我在 cmets 中提到的。 stefan的回答是最好的。这是 Base R 的替代方案:

    df1[!(df1$ID %in% df2$ID),]
    
      ID Value
    3  3    30
    4  4    40
    5  5    50
    

    基准:

    【讨论】: