如何根据R中一行中的两个连续列值对数据帧进行子集化

时间:2013-11-24 20:29:47

标签: r subset

我有以下两个数据框

  

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循环它仍然只获得第一个值

2 个答案:

答案 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列。