2016-10-05 80 views
2

我有兩個數據框的座標。每個數據幀都有兩個'set'座標和一個座標,它是一個範圍(由範圍的開始和結束的兩列表示)。實際的數據幀非常大,約40,000行。這裏有一些虛擬數據:如何在R中的兩個數據幀中查找重疊行?

hdata<-data.frame(distance=c(1:12),x=c(1,1,1,1,1,1,2,2,2,2,2,2),z=c(1,1,1,2,2,2,1,1,1,2,2,2), 
       ystart=c(0.5,3,3,3,3,1.5,3,3,3,1.5,1.5,0.5),yend=c(1.5,4,4,4,4,2.5,4,4,4,2.5,2.5,1.5)) 
vdata<-data.frame(distance=c(1:12),x=c(1,1,1,1,1,1,2,2,2,2,2,2),y=c(1,1,1,2,2,2,1,1,1,2,2,2), 
       zstart=c(0.5,3,1.5,3,3,3,3,3,1.5,1.5,1.5,3),zend=c(1.5,4,2.5,4,4,4,4,4,2.5,2.5,2.5,4)) 


> vdata 
# distance x z ystart yend 
#1   1 1 1 0.5 1.5 
#2   2 1 1 3.0 4.0 
#3   3 1 1 3.0 4.0 
#4   4 1 2 3.0 4.0 
#5   5 1 2 3.0 4.0 
#6   6 1 2 1.5 2.5 
#7   7 2 1 3.0 4.0 
#8   8 2 1 3.0 4.0 
#9   9 2 1 3.0 4.0 
#10  10 2 2 1.5 2.5 
#11  11 2 2 1.5 2.5 
#12  12 2 2 0.5 1.5 

> hdata 
# distance x y zstart zend 
#1   1 1 1 0.5 1.5 
#2   2 1 1 3.0 4.0 
#3   3 1 1 1.5 2.5 
#4   4 1 2 3.0 4.0 
#5   5 1 2 3.0 4.0 
#6   6 1 2 3.0 4.0 
#7   7 2 1 3.0 4.0 
#8   8 2 1 3.0 4.0 
#9   9 2 1 1.5 2.5 
#10  10 2 2 1.5 2.5 
#11  11 2 2 1.5 2.5 
#12  12 2 2 3.0 4.0 

我想查找座標重疊的行。因此,例如,命中將是第1行數據與hdata的第1行,因爲兩者都具有x = 1,vdata的z座標落在hdata的z範圍內,並且hdata的y座標落在y的範圍內VDATA。

> vdata[1,] 
    distance x z ystart yend 
1  1 1 1 0.5 1.5 
> hdata[1,] 
    distance x y zstart zend 
1  1 1 1 0.5 1.5 

這個虛擬數據集的正確的輸出應該是這樣的:

> results 
    vdistance hdistance x ystart yend zstart zend 
1   1   1 1 0.5 1.5 0.5 1.5 
2   12   9 2 0.5 1.5 1.5 2.5 
3   10  10 2 1.5 2.5 1.5 2.5 
4   11  10 2 1.5 2.5 1.5 2.5 
5   10  11 2 1.5 2.5 1.5 2.5 
6   11  11 2 1.5 2.5 1.5 2.5 

我做的嵌套一個非常緩慢和複雜的一堆用於循環和if/else if語句,試圖梳理這些了。這對於我的海量數據集來說太長了。我嘗試通過將數據框分爲x和y以及x和z,然後僅檢查每個框架的第一個x座標,並通過排序ystart和zstart列,然後停止z或y超出範圍但仍然太慢。

有關更好方法的任何想法?

+0

非球菌加入'data.table'的開發版本(1.9.7)將做到這一點。請參閱['新功能]中的第3項(https://github.com/Rdatatable/data.table/blob/master/NEWS.md) – SymbolixAU

+0

此外,[此問題](http://stackoverflow.com/q/35565149/5977215)有一些如何做到這一點的例子,[Arun的回答](http://stackoverflow.com/a/38663460/5977215)顯示非Equi連接在行動中(他是數據的共同開發者。表) – SymbolixAU

+0

感謝有用的鏈接Symbolix! – OxL

回答

2

考慮使用條件過濾器合併:

mdf <- merge(hdata, vdata, by="x") 

finaldf <- mdf[(mdf$z >= mdf$zstart & mdf$z <= mdf$zend) & 
       (mdf$y >= mdf$ystart & mdf$y <= mdf$yend),] 

rownames(finaldf) <- seq(nrow(finaldf)) 
colnames(finaldf) <- c("x", "hdistance", "z", "ystart", "yend", 
          "vdistance", "y", "zstart", "zend") 
finaldf <- finaldf[c("hdistance", "vdistance", "x", 
        "ystart", "yend", "zstart", "zend")] 

finaldf 
# hdistance vdistance x ystart yend zstart zend 
# 1   1   1 1 0.5 1.5 0.5 1.5 
# 2  10  10 2 1.5 2.5 1.5 2.5 
# 3  10  11 2 1.5 2.5 1.5 2.5 
# 4  11  10 2 1.5 2.5 1.5 2.5 
# 5  11  11 2 1.5 2.5 1.5 2.5 
# 6  12   9 2 0.5 1.5 1.5 2.5 
+0

非常感謝!它適用於我的測試數據集。當我在40,000行的數據框上嘗試它時,它陷入了合併步驟,這非常緩慢......但是我意識到,我實際上已經連接了我的數據太早,並且它在我運行在較小的子集上時運行良好(〜6000行)。 (合併步驟需要約4秒,其餘需要約1秒) – OxL

+0

太棒了!總是喜歡聽到解決方案如何在現實生活中練習。很高興我能幫上忙。 – Parfait

相關問題