从一个数据框中过滤出在另一个数据框中存在的行。

25
假设我有一个较大的数据框和一个较小的数据框。如果较小的数据框包含在较大的数据框中,如何从较大的数据框中减去较小数据框的行,得到以下结果:

较大数据框 - 较小数据框

例如:

较小数据框:

     ID       CSF1PO CSF1PO.1 D10S1248 D10S1248.1 D12S391 D12S391.1
203079_BA_M     10       11       14         16      -9        -9
203079_BA_F      8       12       14         17      -9        -9
203080_BA_M     10       12       13         13      -9        -9

大型数据框:

      ID      CSF1PO CSF1PO.1 D10S1248 D10S1248.1 D12S391 D12S391.1
203078_MG_M     -9       -9       15         15      18        20
203078_MG_F     -9       -9       14         15      17        19
203079_BA_M     10       11       14         16      -9        -9
203079_BA_F      8       12       14         17      -9        -9
203080_BA_M     10       12       13         13      -9        -9
203080_BA_F     10       11       14         16      -9        -9
203081_MG_M     10       12       14         16      -9        -9
203081_MG_F     11       12       15         16      -9        -9
203082_MG_M     11       11       13         15      -9        -9
203082_MG_F     11       11       13         14      -9        -9

这个小的数据框对应于大的数据框中的第3、4和5行。


1
如果ID是一个键(唯一确定了行的其余部分),那么Big[!(Big$ID %in% Small$ID),]应该可以工作。没有键会更混乱,我猜。 - Frank
ID实际上是行名...不是数据框中的列,但如果需要的话,我可以将其变成一列。 - vitor
1
不需要。只需在Big$ID的位置使用rownames(Big) - Frank
3个回答

21

试试这个:

BigDF[ !(BigDF$ID %in% SmallDF$ID), ]

18
在dplyr中:
library(dplyr)

setdiff(BigDF, SmallDF)

更多信息:Hadley的 dply cheatsheethttps://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf

简明的 Set Operations 函数及其示例 http://rpackages.ianhowson.com/cran/dplyr/man/setops.html(但整个 数据操作语法 是一个很好的资源)

尽管以下内容并非直接回答您的问题,但它对我来说经常相关(并且非常有用)

如果您想要捕获新数据框和同一记录的先前版本之间发生的新更改,您需要使代码如下所示:

setdiff(NewDF, OldDF)

1

当列数和类型匹配时,setdiff很好用,但是当小数据框从大数据框中有一部分列时,就会出现问题。

dplyr中的anti-join是一种替代方法,它提供了大数据框中不在小数据框中的所有行。它保留了大数据框中的列,这正是您所需要的,而不像其他连接那样与小数据框的列组合。请参见链接http://rpubs.com/williamsurles/293454

如果ID是列名,则应将其更改为字符,否则R会默认强制转换为字符并给出警告,但会给出正确结果。我使用以下代码得到与setdiff()相同的答案:

small_df$ID <- as.character(small_df$ID)
big_df$ID   <- as.character(big_df$ID)
result      <- anti_join(big_df,small_df)

结果 =

ID         CSF1P0 CSF1P0.1 D10S1248 D10S1248.1 D12S391 D12S391.1
203078_MG_M    -9   -9      15       15         18       20 
203078_MG_F    -9   -9      14       15         17       19
203080_BA_F    10   11      14       16         -9       -9  
203081_MG_M    10   12      14       16         -9       -9  
203081_MG_F    11   12      15       16         -9       -9 
203082_MG_M    11   11      13       15         -9       -9  
203082_MG_F    11   11      13       14         -9       -9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接