R:创建网格并使用 for 循环检查每个单元格中的行

R: Creating Grid and checking what row falls into each cell with for loop

我翻了很多论坛帖子都没有找到答案。我有一个很大的纬度和经度列表,我想制作一个网格,并基于该网格为每对 lat/longs 分配一个来自该网格的单元格引用。最后我想根据单元格引用分配值。例如。 Lat 39.5645 和 long -122.4654 落入网格单元格参考 1,该单元格中的谋杀总数为 16,攻击总数为 21。有更好的方法可以做到这一点,但这是我唯一的方法知道的。

#number of segments, this determines size of grid
segments <- 5
#use these to dvide up the arrays
Xcounter <-(max(cleantrain$X)-min(cleantrain$X))/segments
Ycounter <-(quantile (cleantrain$Y,.9999)-min(cleantrain$Y))/segments

#arrays created from the counter and lat and longs
Xarray <- as.data.frame(seq(from=min(cleantrain$X), to=max(cleantrain$X), by=Xcounter))
Yarray <-as.data.frame(seq(from=min(cleantrain$Y), to=quantile(cleantrain$Y,.9999), by=Ycounter))

#the max for the latitude is 90 but the .9999 percentile is ~39,
# but I still want the grid to include the 90
Yarray[6,1]<-max(cleantrain$Y)
#create dummy column so I know what the values shouldn't be when I print the results
cleantrain$Area <- seq(from =1, to=nrow(cleantrain), by =1)
#for loop that goes through once for each row in my data
for (k in 1:100) {
  #this loop goes through the longitudes 
  for (i in 1:seg-1) {
    #this loop goes though the latitudes 
    for (j in 1:seg-1){
      #should check if the row fits into that grid 
      if(cleantrain$Y[k] < Yarray[(j+1),1] && 
          cleantrain$X[k] < Xarray[(i+1),1] &&
          cleantrain$Y[k] >= Yarray[j,1] &&
           cleantrain$X[k] >= Xarray[i,1]){
        #writes to the row the cell reference
        cleantrain$Area[k] <- ((i-1)*segments+j)
      } 
    }
  }
}
#check the results
cleantrain$Area[1:100]

如果您只将 i 值写入 cleantrain$Area,它将始终打印 1 而不是 1-5。但是 j for 循环会像预期的那样打印 1-5。但是,如果您进入 if 语句并切换 i 和 j 循环引用,则 j 将始终为 1,而 i 将始终为 1-5。

这是我的数组值

#Yarray
    1                                                                          37.70788
    2                                                                          37.73030
    3                                                                          37.75272
    4                                                                          37.77514
    5                                                                          37.79756
    6                                                                          37.81998
#Xarray
1                                                            -122.5136
2                                                            -122.1109
3                                                            -121.7082
4                                                            -121.3055
5                                                            -120.9027
6                                                            -120.5000

编辑:

这是前 10 个纬度和经度:

 cleantrain$Y[1:10]
 [1] 37.77460 37.77460 37.80041 37.80087 37.77154 37.71343 37.72514 37.72756 37.77660 37.80780
cleantrain$X[1:10]
 [1] -122.4259 -122.4259 -122.4244 -122.4270 -122.4387 -122.4033 -122.4233 -122.3713 -122.5082 -122.4191

上面的代码不可重现,但我想我明白了你想要实现的目标。在这个例子中,我假设我有一堆随机生成的 x 坐标和 y 坐标。 x[0,1] 和 y 在 [10, 20].

df <- data.frame(xcoord = runif(1000), ycoord = runif(1000, min=10, max=20))

要解决将点分配给网格的问题,我们只需要将点映射到一些定义的部分。最简单的方法是通过 cut 函数。例如,要将 xcoord 映射到一串长度为 10 的数字,将 ycoord 映射到一串长度为 9 的数字,我们会这样做:

df$x_cut <- as.numeric(cut(df$xcoord, 10))
df$y_cut <- as.numeric(cut(df$ycoord, 9))

如果你想在特定的时间间隔内切割东西,你可以这样做:cut(runif(10), c(0, 0.2, 0.4, 0.6, 0.8, 1)),参见this answer for other ways

现在我们基本上有了我们的网格。如果您想将其映射到单个数字,我们可以创建这样的映射。

grid_index <- expand.grid(x_cut=1:xlength, y_cut=1:ylength)
grid_index$index <- row.names(grid_index)

合并两个数据框得到全图。

df_all <- merge(df, grid_index)

完整代码:

df <- data.frame(xcoord = runif(1000), ycoord = runif(1000, min=10, max=20))

df$x_cut <- as.numeric(cut(df$xcoord, 10))
df$y_cut <- as.numeric(cut(df$ycoord, 9))

grid_index <- expand.grid(x_cut=1:xlength, y_cut=1:ylength)
grid_index$index <- row.names(grid_index)

df_all <- merge(df, grid_index)