我有以下两个数据框
miRNA_expval_uni:
miRNA Genenames Pubmed_Id
hsa-miR-181a-5p DUSP6 17382377
hsa-miR-20a-5p HIF1A 18632605
hsa-miR-146a-5p CXCR4 18568019
hsa-miR-146a-5p CXCR4 20375304
hsa-miR-200b-3p RND3 20683643
hsa-miR-328-3p PTPRJ 22564856
hsa-miR-122-5p CYP7A1 20351063
hsa-miR-222-3p STAT5A 20489169
hsa-miR-21-5p RASGRP1 20483747
hsa-miR-21-5p RASGRP1 18591254
GenemiRNA:
Genes miRNA
RND3 hsa-miR-200b-3p
RASGRP1 hsa-miR-21-5p
PTPRJ hsa-miR-328-3p
ELK3 hsa-miR-19b-3p
ELK3 hsa-miR-454-3p
ELK3 hsa-miR-301b
ELK3 hsa-miR-4295
ELK3 hsa-miR-3666
我想从数据框miRNA_expval_uni中进行子集化,其中GenemiRNA中的行等于miRNA_expval_uni中的行。我一直在尝试不同的方法,但没有一个有效。我试过了:
set <- rbind(set, GenemiRNA[(GenemiRNA$Genes %in%
miRNA_expval_uni$Genenames):(GenemiRNA$miRNA
%in% miRNA_expval_uni$miRNA), ])
我也试过使用for循环它仍然只获得第一个值
答案 0 :(得分:1)
这是我的解决方案,它可能不是最优雅的,但它可以工作,只使用R中的基础包。
获取GenemiRNA中miRNA_expval_uni中匹配基因的指标。
idx1 = lapply(miRNA_expval_uni$Genenames,function(x) which(x==GenemiRNA$Genes))
接下来获取GenemiRNA中miRNA_expval_uni中匹配miRNA的指标。
idx2 = sapply(miRNA_expval_uni$miRNA,function(x) which(x==GenemiRNA$miRNA))
现在我们要比较两组不同的指标,看看哪些行在和中都匹配,两者都匹配到miRNA_expval_uni中的同一行。 / p>
result =mapply(intersect,idx1,idx2)
现在我们只需要清理输出以获取子集标记列表。
result = sort(unique(unlist(result)))
set = GenemiRNA[result,]
Set是GenemiRNA的子集,其中GenemiRNA中的行与miRNA_expval_uni中的行完全匹配。如果您想要反向,只需在上面的解决方案中切换名称和相应的列引用。
miRNA,Genenames,Pubmed_Id
hsa-miR-181a-5p,DUSP6,17382377
hsa-miR-20a-5p,HIF1A,18632605
hsa-miR-146a-5p,CXCR4,18568019
hsa-miR-146a-5p,CXCR4,20375304
hsa-miR-200b-3p,RND3,20683643
hsa-miR-328-3p,PTPRJ,22564856
hsa-miR-122-5p,CYP7A1,20351063
hsa-miR-222-3p,STAT5A,20489169
hsa-miR-21-5p,RASGRP1,20483747
hsa-miR-21-5p,RASGRP1,18591254
hsa-miR-454-3p,ELK3,12345
hsa-miR-221-5p,ELK3,12345
hsa-miR-454-3p,BOB,12345
hsa-miR-3666,BOBBY,12345
Genes, miRNA
RND3,hsa-miR-200b-3p
RASGRP1,hsa-miR-21-5p
PTPRJ,hsa-miR-328-3p
ELK3,hsa-miR-19b-3p
ELK3,hsa-miR-454-3p
ELK3,hsa-miR-301b
ELK3,hsa-miR-4295
ELK3,hsa-miR-3666
Genes miRNA
1 RND3 hsa-miR-200b-3p
2 RASGRP1 hsa-miR-21-5p
3 PTPRJ hsa-miR-328-3p
5 ELK3 hsa-miR-454-3p
如果您在哪里使用以下内容:subset(GenemiRNA,(Genes%in%miRNA_expval_uni$Genenames)&(miRNA%in%miRNA_expval_uni$miRNA))
这基本上是您最初尝试的内容,它将失败。这是因为它会返回其基因和miRNA在其他数据集中匹配的任何行,但不一定只只有那些匹配到同一行/位置的那些。如果你在上面的测试数据上运行它,你得到:
Genes miRNA
1 RND3 hsa-miR-200b-3p
2 RASGRP1 hsa-miR-21-5p
3 PTPRJ hsa-miR-328-3p
5 ELK3 hsa-miR-454-3p
8 ELK3 hsa-miR-3666 **INCORRECT MATCH**
这是因为ELK3
在两个数据集中,hsa-miR-3666
也是如此。但是,它们永远不会出现在同一行中,因此结果表中的最后一个值是错误的。如果您使用我的解决方案,则不会出现此错误。
这个问题实际上相当复杂,因为两个数据集中都可能存在重复值。您尝试不起作用的原因是因为您使用%in%,这实际上只是对match()的调用。以下是来自match()文档的片段(强调我的):
匹配返回第二个参数中(第一个)匹配位置的向量。
%in%是一个更直观的界面作为二元运算符,它返回一个逻辑向量,指示其左操作数是否匹配。
%in%目前定义为 “%in%”&lt; - function(x,table)match(x,table,nomatch = 0)&gt; 0
因此,调用%in%会告诉您至少有一个匹配,但它不会告诉您是否存在多个匹配(匹配功能相同) )。这就是为什么你的方法只返回“第一个值”,你只得到第一场比赛,而不是所有的比赛。
因此,正确的方法是为每一行生成属性x
中所有匹配项的列表。然后比较每个列表,找到给定行的所有列表中的公共元素。这些常见元素的行指示是您所需的子集标记。
对我的所作所为有任何疑问?在下面发表评论,我将尽我所能解释。
注意:您需要在数据设置中读取字符串AsFactors = FALSE才能正常工作,因为有时比较因素会导致“问题”。
注意2:正如一些人所建议的那样,您也可以使用data.table
包。请注意,它将组合您的数据表,因此它不会严格回答您的问题(即,您将获得一个输出合并来自两者的数据,因此它将包含PubMedID
列和{{1}尽管RASGRP1
中只有一个
注3:虽然* apply函数系列起初非常混乱,但要了解它们中的每一个以及何时/如何使用它们是非常有用的技能。下面可以找到一个很好的介绍(我个人发现R文档太混乱,无法直观地理解每个函数)
https://nsaunders.wordpress.com/2010/08/20/a-brief-introduction-to-apply-in-r/
答案 1 :(得分:0)
我打算拨打第一个A
和第二个B
。这是使用data.table
包的解决方案:
require(data.table) ## >= 1.9.2
setDT(A) ## convert the data.frame to data.tables by reference
setDT(B)
# set the columns on which you'd want the join to be based on
setkey(A, miRNA, Genenames)
setkey(B, miRNA, Genes)
# join
A[B, nomatch=0L]
# miRNA Genenames Pubmed_Id
# 1: hsa-miR-200b-3p RND3 20683643
# 2: hsa-miR-21-5p RASGRP1 20483747
# 3: hsa-miR-21-5p RASGRP1 18591254
# 4: hsa-miR-328-3p PTPRJ 22564856
nomatch
参数确保仅返回匹配的那些行。如果您将其删除,则系统会返回B
中的所有行,NA
为相应的A
列。