我有一个包含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
我可以想到几种方法,使用循环,使用应用和匹配的组合,甚至从sp
或maptools
中拉出一些大的空间枪。但所有这些都非常缓慢。我预感到有一些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)])
我无法从这里看出它是光滑还是可怕 - 无论哪种方式,应用功能对于完整的数据帧来说都太慢了。)
答案 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