簡體   English   中英

如何基於R中一行中的兩個連續列值對數據幀進行子集

[英]how to subset a data frame based on two consecutive column values in a row in R

我有以下兩個數據框

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循環,它仍然只獲取第一個值

這是我的解決方案,它可能不是最優雅的,但它可以工作並且僅使用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中的同一行匹配。

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**

這是因為ELK3hsa-miR-3666都在兩個數據集中。 但是,它們永遠不會出現在同一行中,因此結果表中的最后一個值是錯誤的。 如果使用我的解決方案,您不會收到此錯誤。

為什么您的嘗試不起作用

這個問題實際上相當復雜,因為兩個數據集中都可能有重復的值。 您的嘗試不起作用的原因是因為您正在使用%in%,這實際上只是對match()的調用。 以下是match()文檔中的摘錄(重點是我的):

match返回其第二個參數的第一個(第一個)匹配位置的向量。

%in%是一個更直觀的二進制運算符接口,它返回一個邏輯向量,指示其左操作數是否匹配。

%in%當前定義為“%in%” <-function(x,table)match(x,table,nomatch = 0)> 0

因此,調用%in%會告訴您至少有一個匹配項,但不會告訴您是否有多個匹配項 (match函數也是如此)。 這就是為什么您的方法僅返回“第一個值”的原因 ,而您僅獲得第一個匹配項,而不是所有匹配項。

因此,正確的方法是為每一行生成屬性x中所有匹配項的列表。 然后比較每個列表,找到給定行的所有列表中的公共元素。 這些常見元素的行索引是您所需的子集索引。

對我的工作有任何疑問嗎? 在下面發表評論,我將盡力而為。

注意:您可能需要讀入數據設置stringAsFactors = FALSE才能使它起作用,因為有時比較因素可能會導致“問題”。

注意2:正如一些建議所建議的,您也可以為此使用data.table包。 請注意,它將合並您的數據表,因此它不會嚴格回答您的問題(即,您將獲得合並兩個數據的輸出,因此,盡管其中只有一個,但它將包含PubMedID列和兩個RASGRP1條目GenemiRNA

注意3:盡管* apply函數家族一開始非常令人困惑,但是了解每個函數以及何時/如何使用它們是非常有用的技能。 可以在下面找到很好的介紹(我個人發現R文檔太混亂而無法直觀了解每個功能)

https://nsaunders.wordpress.com/2010/08/20/a-brief-introduction-to-apply-in-r/

我將稱第一個為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中的所有行,以及對應於A列的NA

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM