4

我有一个包含 XY 坐标的大型数据框(约 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我可以想到几种方法来做到这一点,使用循环,使用 apply 和 match 的组合,甚至从or中拉出一些大空间枪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)])

从这里我无法判断它是光滑还是可怕 - 无论哪种方式,apply 函数对于完整的数据框来说都太慢了。)

4

2 回答 2

3

以 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)]

顺便说一句,强制复杂以进行二维匹配的好技巧。

于 2013-08-06T07:24:06.613 回答
2

你只需要两个滚动合并:

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
于 2013-08-06T14:52:00.550 回答