如何使用 R 中的条件删除两者中的重复行
How to remove duplicate rows in both using a condition in R
我的数据是这样的:
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
可能与 Remove duplicates column combinations from a dataframe in R
重复
在此处调整答案:
dff[!duplicated(dff[c('RES1','RES2')]),]
您可以使用此代码:
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 创建两个字符向量 v1
、v2
(注意 paste
默认使用 space分隔符,也许你可以使用另一个字符或字符串来更安全(例如 |
、@
、;
等...)
结果:
> 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
函数总是 returns 在列上产生结果)。
结果:
[,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(matrix) 的逻辑向量,当一行是前一行的副本时为 TRUE,所以在我们的例子中,我们得到:
[1] FALSE TRUE FALSE FALSE FALSE
# i.e. the second row is a duplicate
5) 最后我们用这个vector过滤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
我的数据是这样的:
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
可能与 Remove duplicates column combinations from a dataframe in R
重复在此处调整答案:
dff[!duplicated(dff[c('RES1','RES2')]),]
您可以使用此代码:
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 创建两个字符向量 v1
、v2
(注意 paste
默认使用 space分隔符,也许你可以使用另一个字符或字符串来更安全(例如 |
、@
、;
等...)
结果:
> 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
函数总是 returns 在列上产生结果)。
结果:
[,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(matrix) 的逻辑向量,当一行是前一行的副本时为 TRUE,所以在我们的例子中,我们得到:
[1] FALSE TRUE FALSE FALSE FALSE
# i.e. the second row is a duplicate
5) 最后我们用这个vector过滤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