R中的行setdiff

时间:2015-09-24 11:37:07

标签: r

对于两个数据框df.1df.2,我想知道不在df.1中的df.2行,即已消失或已更改的行。 这是一个例子:

df.1 = cbind.data.frame(a = 1:4, b = 2:5, c = 99:102)
> df.1
  a b   c
1 1 2  99
2 2 3 100
3 3 4 101
4 4 5 102

df.2 = cbind.data.frame(a = c(1:3,7), b = c(3,3:4,9), c=c(99:100, 102, 105))
> df.2
  a b   c
1 1 3  99
2 2 3 100
3 3 4 102
4 7 9 105

所以这里我想要的输出是df.1的第1,3和4行:

> desired.output
  a b   c
1 1 2  99
3 3 4 101
4 4 5 102

如果df.1df.2是向量,我可以使用setdiff(df.1, df.2),但我没有看到一种简单/优雅的方式将其应用于数据框。

有没有比我想到的这些变通方法更优雅的东西:

  • 逐列比较df.1df.2,然后从所有列中获取联合
  • 使数据框成为所有行的列表,然后使用setdiff并转换回dataframe

3 个答案:

答案 0 :(得分:4)

在dplyr中使用anti_join很方便。

library(dplyr)
anti_join(df.1,df.2)
Joining by: c("a", "b", "c")
  a b   c
1 1 2  99
2 4 5 102
3 3 4 101

答案 1 :(得分:3)

我认为,最优雅(语法糖和非常高效)是使用data.table包:

library(data.table)
setDT(df.1)[!df.2, on = names(df.1)]
#    a b   c
# 1: 1 2  99
# 2: 3 4 101
# 3: 4 5 102

请注意,这与以下内容不同:

setDT(df.2)[!df.1, on = names(df.2)]
#    a b   c
# 1: 1 3  99
# 2: 3 4 102
# 3: 7 9 105

答案 2 :(得分:2)

使用sqldf

library(sqldf)
sqldf('SELECT * FROM [df.1] EXCEPT SELECT * FROM [df.2]')

输出:

  a b   c
1 1 2  99
2 3 4 101
3 4 5 102