![](/img/trans.png)
[英]R - How to make a subset of columns based on values in a row in a data frame
[英]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**
這是因為ELK3
和hsa-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.