如何使用R中的条件删除两者中的重复行

时间:2016-04-22 19:38:14

标签: r dataframe comparison remove-if

我拥有的数据是这样的:

RES1 <- c("A","B","A","A","B")
RES2 <- c("B","A","A","B","A")
VAL1 <-c(3,5,3,6,8)
VAL2 <- c(5,3,7,2,7)
dff <- data.frame(RES1,VAL1,RES2,VAL2)
dff
  RES1 VAL1 RES2 VAL2
  1    A    3    B    5 
  2    B    5    A    3
  3    A    3    A    7
  4    A    6    B    2
  5    B    8    A    7

我想删除已经拥有相同res1-res2对的行。例如:A 3与B 5交互。这就是我想要的信息。我不在乎哪一对是第一个。 B 5与A 3或A 3与B 5.我想得到的是以下数据帧:

output
  RES1 VAL1 RES2 VAL2
   1    A    3    B    5
   2    A    3    A    7
   3    A    6    B    2
   4    B    8    A    7

然后我想对另一个数据框执行相同的操作,例如:

RES3 <- c("B","B","B","A","B")
RES4 <- c("A","A","A","A","B")
VAL4 <- c(3,7,5,3,8)
VAL3 <- c(5,8,3,7,3)
df2 <- data.frame(RES3,VAL3,RES4,VAL4)

df2
  RES3 VAL3 RES4 VAL4
   1     B     5     A     3
   2     B     8     A     7
   3     B     3     A     5
   4     A     7     A     3
   5     B     3     B     8

最后,我只想保持相互配对(在我的定义中,两对都是相同的,保持一对是必不可少的:“A 5” - “B 3”与“B 3”相同 - “A 5 “换句话说,顺序并不重要。

我希望的最终输出应该具有以下唯一且存在于两个数据帧中的对:

mutualpairs
  RESA VALA RESB VALB
  A     3     B     5
  A     3     A     7
  B     8     A     7

2 个答案:

答案 0 :(得分:4)

您可以使用此代码:

dff[!duplicated(t(apply(cbind(paste(dff$RES1,dff$VAL1),paste(dff$RES2,dff$VAL2)),1,sort))),]

等效展开代码:

v1 <- paste(dff$RES1,dff$VAL1)
v2 <- paste(dff$RES2,dff$VAL2)
mx <- cbind(v1,v2)
mxSorted <- t(apply(mx,1,sort))
duped <- duplicated(mxSorted)
dff[!duped,]

说明:

1)我们通过连接列RES1-VAL1和RES2-VAL2来创建两个字符向量v1v2(注意paste使用空格作为默认分隔符,也许你可以使用另一个字符或字符串更安全(例如|@;等......)
结果:

> v1
[1] "A 3" "B 5" "A 3" "A 6" "B 8"
> v2
[1] "B 5" "A 3" "A 7" "B 2" "A 7"

2)我们使用cbind绑定这两个向量以形成矩阵; 结果:

     [,1]  [,2] 
[1,] "A 3" "B 5"
[2,] "B 5" "A 3"
[3,] "A 3" "A 7"
[4,] "A 6" "B 2"
[5,] "B 8" "A 7"

3)我们使用t(apply(mx,1,sort))对矩阵的每一行的值进行排序;
通过对行进行排序,我们只需将具有相同值的行完全相同(请注意,最后的转置是必要的,因为apply函数始终返回列上的结果)。
结果:

     [,1]  [,2] 
[1,] "A 3" "B 5"
[2,] "A 3" "B 5"
[3,] "A 3" "A 7"
[4,] "A 6" "B 2"
[5,] "A 7" "B 8"

4)在矩阵上调用duplicated,我们得到一个长度= nrow(矩阵)的逻辑向量,为TRUE,其中一行是前一行的副本,所以在我们的例子中,我们得到:< / p>

[1] FALSE  TRUE FALSE FALSE FALSE
# i.e. the second row is a duplicate

5)最后我们使用这个向量来过滤data.frame的行,得到最终结果:

  RES1 VAL1 RES2 VAL2
1    A    3    B    5
3    A    3    A    7
4    A    6    B    2
5    B    8    A    7

答案 1 :(得分:0)

Remove duplicates column combinations from a dataframe in R

可能重复

在这里调整答案:

dff[!duplicated(dff[c('RES1','RES2')]),]