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)
我翻了很多论坛帖子都没有找到答案。我有一个很大的纬度和经度列表,我想制作一个网格,并基于该网格为每对 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)