2014-11-20 61 views
2

我有一個看起來像這樣兩個數據幀:如何比較數據幀1的每一行與數據幀2的每一行?

x=data.frame(Name=c("200003","200260","400826","400863","500710"),Chr=c("chr1","chr1","chr2","chr3","chr3"),Position=c(11880,14415,13000,15000,18000))  
y=data.frame(name=c("geneA","geneB","geneC","geneD","geneE"),chrom=c("chr1","chr1","chr2","chr2","chr3"),Start=c(11873,11878,12000,14361,14361),End=c(14409,14419,14409,16765,19759)) 

> x 
    Name Chr Position 
1 200003 chr1 11880 
2 200260 chr1 14415 
3 400826 chr2 13000 
4 400863 chr3 15000 
5 500710 chr3 18000 

> y 
    name chrom Start End 
1 geneA chr1 11873 14409 
2 geneB chr1 11878 14419 
3 geneC chr2 12000 14409 
4 geneD chr2 14361 16765 
5 geneE chr3 14361 19759 

我想比較x和y,並返回一個數據幀或由x中每個名稱的列表和y的名字具有相同CHROM作爲Chr和(開始,結束)間隔包括位置。例如,

200003 geneA 
200003 geneB 
200260 geneB 
400826 geneC 
400863 geneE 
500710 geneE 

編輯:我用下面的代碼

z=merge(x,y,by.x='Chr',by.y='chrom') 
z=cbind(z,with(z, Position>=Start & Position<=End)) 
z=z[-which(z[,7]=="FALSE"),] 
output=cbind(as.character(z$Name),as.character(z$name)) 

在現實中,X和Y和大型數據集能得到的結果,它需要一段時間merge運行。有一個更好的方法嗎?

+0

這不是一個「應用」問題。你可以創建一個有用的,如果重要的中間與​​'merge'。 – 2014-11-20 19:41:23

+0

也許用'split'或'data.table'?我會看看我是否可以拼湊一個data.table方法。我不是最熟悉DT的人。新版本具有範圍功能。我已經添加了一個標籤,以查看這個珊瑚礁中是否有任何data.table-barracudas。 – 2014-11-21 02:48:38

+0

https://github.com/Rdatatable/data.table/wiki/Installation – 2014-11-21 02:53:50

回答

4

@BondedDust似乎已經刪除他的解決方案。他的解決方案唯一的問題是,關鍵還需要包括chrom

這裏使用的是data.tablefoverlaps。首先,我們將在data.frames轉換爲data.tables:

require(data.table) 
setDT(x) 
setDT(y) 

而且,由於foverlaps作品與區間範圍內,我們會爲x添加一個虛擬列如下:

x[, Position2 := Position] 

現在,對於每個x,我們想知道是否Chr, Position, Position2整個落在之內任何ychrome,Start,End。 - 「CHROM」與「CHR」

setkey(y, chrom, Start, End) 
foverlaps(x, y, by.x=c("Chr", "Position", "Position2"))[, list(Name, name)] 
#  Name name 
# 1: 200003 geneA 
# 2: 200003 geneB 
# 3: 200260 geneB 
# 4: 400826 geneC 
# 5: 400863 geneE 
# 6: 500710 geneE 

列在您的data.frames被命名異常和套管:我們會按如下方式使用y爲「關鍵」。使用一致的名稱可能會更容易。

+0

這非常快!儘管它比我使用慢方法產生更多結果(任何想法?)。猜猜我將不得不探索'data.table'更強大的功能...... – Menglan 2014-11-21 18:35:06

+0

@Menglan,非常高興!如果你能把我和一些測試數據聯繫起來(結果不同),我很樂意看看它。 – Arun 2014-11-21 19:13:18

+0

我自己做了一些測試,發現這是因爲'Chr,Position,Position2'在chrome,Start,End之外''foverlaps'有NA,而這樣的結果不會顯示我是否使用了我的代碼。謝謝! – Menglan 2014-12-05 16:26:54

2

這使或多或少你想要的東西(它不是衣衫襤褸,從x名稱會重複,如果有多個匹配):

library(sqldf) 
sqldf("select x.Name, y.name 
    from x 
    left join y 
    on x.Position between y.Start and y.End 
    and x.Chr = y.chrom") 

    Name name 
1 200003 geneA 
2 200003 geneB 
3 200260 geneB 
4 400826 geneC 
5 400863 geneE 
6 500710 geneE 
+0

我無法加載軟件包,但輸出可以接受。感謝你的回答! – Menglan 2014-11-21 02:25:16

+1

請參閱:https://code.google.com/p/sqldf/#Troubleshooting – 2014-11-21 15:03:59

相關問題