如何在R中的两个数据帧中找到重叠的行?

时间:2016-10-05 01:43:41

标签: r coordinates

我有两个坐标数据框。每个数据框都有两个' set'坐标和一个坐标是一个范围(由范围的起点和终点的两列表示)。实际数据帧非常大,约为40,000行。这是一些虚拟数据:

    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

我想找到坐标重叠的行。因此,例如,命中将是vdata的第1行,其中第1行为hdata,因为两者都有x = 1,vdata&#39; sz坐标属于hdata的z范围,而hdata&#c; sy坐标落在vdata的y范围内。

> 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

我制作了一个非常缓慢而复杂的嵌套for循环和if / else if语句来尝试对它们进行排序。对于我庞大的数据集,它需要太长时间。我尝试通过x和y以及x和z分割数据帧,然后仅检查每个帧的第一个x坐标,并通过ystart和zstart列排序然后停止z或y超出范围,但仍然太慢。

有关更好方法的任何想法吗?

1 个答案:

答案 0 :(得分: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