R:将来自一个(大)数据帧的坐标与来自另一个(大)数据帧的网格单元匹配

时间:2013-08-06 07:13:15

标签: r dataframe data.table

我有一个包含X-Y坐标的大数据框(~200,000行),例如:

points <- data.frame(X = c(1,3,2,5,4), Y = c(4,3,2,2,1))

另一个大型数据框(约1,000,000行),包含空间(矩形)网格的角单元格,例如:

MINX <- rep(0.5:5.5,6)
MINY <- rep(0.5:5.5,each=6)
grid <- data.frame(GridID = 1:36, MINX, MINY, MAXX = MINX+1, MAXY = MINY+1)

我想在“点”数据框中添加一列,用于标识该点所在网格的ID:

X Y GridID
1 4     19
3 3     15
2 2      8
5 2     11
4 1      4

我可以想到几种方法,使用循环,使用应用和匹配的组合,甚至从spmaptools中拉出一些大的空间枪。但所有这些都非常缓慢。我预感到有一些data.table()衬垫,可以在合理的时间内将其拉下来。有没有大师有想法?

(为了记录,这就是我获得网格单元ID的方法:

pt.minx <- apply(points,1, 
             function(foo) max(unique(grid)$MINX[unique(grid)$MINX < foo[1]]))
pt.miny <- apply(points,1, 
             function(foo) max(unique(grid)$MINY[unique(grid)$MINY < foo[2]]))
with(grid, GridID[match(pt.minx+1i*pt.miny, MINX + 1i*MINY)])

我无法从这里看出它是光滑还是可怕 - 无论哪种方式,应用功能对于完整的数据帧来说都太慢了。)

2 个答案:

答案 0 :(得分:2)

以SQL [df]方式执行:

require(sqldf)
sqldf("select X, Y, GridID from grid, pts
       where MINX < X and X < MAXX and MINY < Y and Y < MAXY")

扩展@Roland的评论,你可以在这里使用findInterval

MINX <- MINY <- 0.5:5.5
x <- findInterval(pts$X, MINX)
y <- findInterval(pts$Y, MINY)
grid$GridID[match(MINX[x]+1i*MINY[y], grid$MINX+1i*grid$MINY)]

强迫复杂进行二维匹配的好方法,顺便说一句。

答案 1 :(得分:1)

你需要两个合并滚动:

grid = data.table(grid, key = 'MINX')
points = data.table(points, key = 'X')

# first merge to find correct MAXX
intermediate = grid[points, roll = Inf][, list(MAXX, X = MINX, Y)]

# now merge by Y
setkey(intermediate, MAXX, Y)
setkey(grid, MAXX, MINY)
grid[intermediate, roll = Inf][, list(X, Y = MINY, GridID)]
#   X Y GridID
#1: 1 4     19
#2: 2 2      8
#3: 3 3     15
#4: 4 1      4
#5: 5 2     11