首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在R中找到两个数据的公共行(反之亦然)

如何在R中找到两个数据的公共行(反之亦然)
EN

Stack Overflow用户
提问于 2021-01-03 06:31:01
回答 2查看 128关注 0票数 1

我想找出两个数据帧之间的公共行。要找到常见的行,我可以使用inner_join(), semi_join()merge()。我已经浏览过不同的帖子,包括this。但是,这些行动并没有达到我的目的。因为我在dataframe中的数据有点不同!

有时,数据中的数据反之亦然。就像3rd and 5th rows of dataframe-1 and dataframe-2。Dataframe-1包含A3 A1 0.75,而Dataframe-2包含A1 A3 0.75。我想把这两行放在一起。

我的第一个数据文件看起来就像

代码语言:javascript
复制
  query target weight
1    A1     A2   0.60
2    A2     A5   0.50
3    A3     A1   0.75
4    A4     A5   0.88
5    A5     A3   0.99
6    (+)-1(10),4-Cadinadiene     Falcarinone-10     0.09
7    Leucodelphinidin-100    (+)-1(10),4-Cadinadiene     0.876
8    Lignin  (2E,7R,11R)-2-Phyten-1-ol   0.778
9    (2E,7R,11R)-2-Phyten-1-ol   Leucodelphinidin    0.55
10   Falcarinone     Lignin  1
11   A1  (+)-1(10),4-Cadinadiene     1
12   A2  Lignin-10  1
13   A3  (2E,7R,11R)-2-Phyten-1-ol   1
14   Falcarinone  A6    1
15   A4  Leucodelphinidin    1
16   A4  Leucodelphinidin    1
17   Falcarinone  A100    1
18   A4  Falcarinone     1

第二个dataframe看起来像

代码语言:javascript
复制
  query target
1    A1     A2   
2    A2     A5   
3    A1     A3  // Missing in the output
4    A4     A5   
5    A3     A5  // Missing in the output
6    A3  (2E,7R,11R)-2-Phyten-1-ol   
7    (+)-1(10),4-Cadinadiene     Falcarinone    
8    Leucodelphinidin    (+)-1(10),4-Cadinadiene-100    
9    Lignin-2  (2E,7R,11R)-2-Phyten-1-ol   
10   A11  (+)-1(10),4-Cadinadiene    
11   A2  Lignin  
12   A3  (2E,7R,11R)-2-Phyten-1-0l 
13   Falcarinone  A60    
14   A4  Leucodelphinidin  // Missing in the output

我使用的代码是output <- semi_join(Dataframe-1, Dataframe-2)output <- inner_join(df_only_dd, sample_data_dd_interaction)

我得到的输出

代码语言:javascript
复制
  query target weight
1    A1     A2   0.60
2    A2     A5   0.50

但是,我的预期输出如下

代码语言:javascript
复制
  query target weight
1    A1     A2   0.60
2    A2     A5   0.50
3    A3     A1   0.75
4    A4     A5   0.88
5    A5     A3   0.99
6    A4  Leucodelphinidin  1

可复制代码在下面给出

代码语言:javascript
复制
df_1 <- read.table(text="query   target     weight
A1  A2  0.6
A2  A5  0.5
A3  A1  0.75
A4  A5  0.88
A5  A3  0.99
(+)-1(10),4-Cadinadiene     Falcarinone     0.09
Leucodelphinidin    (+)-1(10),4-Cadinadiene     0.876
Lignin  (2E,7R,11R)-2-Phyten-1-ol   0.778
(2E,7R,11R)-2-Phyten-1-ol   Leucodelphinidin    0.55
Falcarinone     Lignin  1
A1  (+)-1(10),4-Cadinadiene     1
A2  Lignin  1
A3  (2E,7R,11R)-2-Phyten-1-ol   1
Falcarinone  A6    1
A4  Leucodelphinidin    1
A4  Leucodelphinidin    1
Falcarinone  A100    1
A5  Falcarinone     1", header=TRUE)
代码语言:javascript
复制
df_2 <- read.table(text="query   target
A1  A2 
A2  A5
A1  A3  
A4  A5  
A3  A5  
(+)-1(10),4-Cadinadiene     Falcarinone    
Leucodelphinidin    (+)-1(10),4-Cadinadiene-100    
Lignin-2  (2E,7R,11R)-2-Phyten-1-ol   
A11  (+)-1(10),4-Cadinadiene    
A2  Lignin  
A3  (2E,7R,11R)-2-Phyten-1-0l 
Falcarinone  A6    
A4  Leucodelphinidin  ", header=TRUE)

任何建议都会受到赞赏。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-01-03 10:48:54

您可以编写一个小函数,即sort的两个数据帧的前两列的行,然后merge它们。

代码语言:javascript
复制
sc <- function(x, i) setNames(cbind(data.frame(t(apply(x[i], 1, sort))), x[-i]), names(x))

res <- merge(sc(df_1, 1:2), sc(df_2, 1:2))
res[!duplicated(res), ]  ## remove duplicates
#                      query           target weight
# 1  (+)-1(10),4-Cadinadiene      Falcarinone   0.09
# 2                       A1               A2   0.60
# 3                       A1               A3   0.75
# 4                       A2               A5   0.50
# 5                       A2           Lignin   1.00
# 6                       A3               A5   0.99
# 7                       A4               A5   0.88
# 8                       A4 Leucodelphinidin   1.00
# 10                      A6      Falcarinone   1.00

编辑

使用data.table解决方案,这应该是更有效的内存。

代码语言:javascript
复制
library(data.table)
setDT(df_1)[,c("query", "target") := list(pmin(query,target), pmax(query,target))]
setDT(df_2)[,c("query", "target") := list(pmin(query,target), pmax(query,target))]
res <- merge(df_1[!duplicated(df_1),], df_2, allow.cartesian=TRUE)
res
#                      query           target weight
# 1: (+)-1(10),4-Cadinadiene      Falcarinone   0.09
# 2:                      A1               A2   0.60
# 3:                      A1               A3   0.75
# 4:                      A2               A5   0.50
# 5:                      A2           Lignin   1.00
# 6:                      A3               A5   0.99
# 7:                      A4               A5   0.88
# 8:                      A4 Leucodelphinidin   1.00
# 9:                      A6      Falcarinone   1.00

要想拿回"data.frame",只需做setDF(res)

票数 1
EN

Stack Overflow用户

发布于 2021-01-03 08:00:25

也许可以试试:

代码语言:javascript
复制
output <- merge(df_1, df_2, all=T)

然后,不管排序如何,都要检查重复的行,类似于:

代码语言:javascript
复制
same.rows <- duplicated(t(apply(output, 1, sort)))

返回标志向量的

代码语言:javascript
复制
FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE

然后,可以保留为FALSE的行。

代码语言:javascript
复制
output[which(same.rows==F),]


query target weight
1    A1     A2   0.60
2    A1     A3   0.75
3    A2     A5   0.50
5    A3     A5   0.99
6    A4     A5   0.88

说得通吗?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65547240

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档