2016-10-05 81 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

相关问题