使用 st_distance 计算到特定点的最近距离
Calculating nearest distance to specific points using st_distance
我刚刚开始使用 R 和空间分析,所以我缺少很多基础知识!
我的数据包含学校地址。对于每所学校,我想计算到最近学校的距离。我的数据还包含有关 "special features" 所学校的信息。此变量 (sps) 编码为 1 ("with special features") 或 0 ("without special features")。我想计算从学校 "with special features" 到学校 "without special features" 的距离。这是我的数据的样子:
head(data01)
id lon lat sps
1 11725 6.932546 50.38269 0
2 11739 6.975160 50.48649 1
3 26883 6.987575 50.50857 0
到目前为止,我设法使用 st_distance 命令和以下代码计算到最近学校的距离。不幸的是,在使用此代码时,在某些情况下最近的学校都有 "special features"。我只想要从 1 -> 0 或 0 ->1 而不是 1->1!
的距离
my_sf <- st_as_sf(data01,
coords = c("lon", "lat"), # x, y (order matters)
crs = 4326)
dist.mat <- st_distance(my_sf) # Great Circle distance since in lat/lon
# Number within 1.5km: Subtract 1 to exclude the point itself
num.1500 <- apply(dist.mat, 1, function(x) {
sum(x < 1500) - 1
})
# Calculate nearest distance
nn.dist <- apply(dist.mat, 1, function(x) {
return(sort(x, partial = 2)[2])
})
# Get index for nearest distance
nn.index <- apply(dist.mat, 1, function(x) { order(x, decreasing=F)[2] })
n.data <- data01
colnames(n.data)[1] <- "neighbor"
colnames(n.data)[2:ncol(n.data)] <-
paste0("n.", colnames(n.data)[2:ncol(n.data)])
mydata2 <- data.frame(data01,
n.data[nn.index, ],
n.distance = nn.dist,
radius1500 = num.1500)
rownames(mydata2) <- seq(nrow(mydata2))
感谢帮助!!
干杯,k
编辑:
我的最终数据集应该是这样的:
head(data01)
id lon lat sps dist
11725 6.932546 50.38269 0 xxxx
11739 6.975160 50.48649 1 xxxx
26883 6.987575 50.50857 0 xxxx
Dist 是到下一所学校的距离(0-> 1 或 1 -> 0)
二维欧几里德中两点之间距离的公式space(毕达哥拉斯):
sqrt( (x1-x2)**2 + (y1-y2)**2)
我们可以创建一个函数来计算它(您可以为 %>%
运算符调用 library(magrittr)
):
dist = function(x1,x2,y1,y2){
sqrt( (x1-x2)**2 + (y1-y2)**2) %>% return()
}
创建一个条件向量(不是强制性的,但它会使代码更具可读性。如果你知道如何,你可以直接内联条件)
condition = data01$sps %>% as.logical()
现在我们可以使用 lapply
:
lapply(1:nrow(data01), function(x){
if(condition[x]){
dist(data01$lon[!condition],
data01$lon[x],
data01$lat[!condition],
data01$lat[x])
}else{
dist(data01$lon[condition],
data01$lon[x],
data01$lat[condition],
data01$lat[x])
}
})
该代码未经测试,但它应该会生成一个向量列表,每个向量应该给出到具有相反 sps 值的学校的距离。第一个向量将对应于所有其他向量到它的距离等...
此解决方案还保留了邻居的顺序,这样向量中的第一个距离将始终对应于对面 sps 组的第一个邻居。
关于如何处理向量列表的问题,当然你可以将其作为列表保存到名为distList
:
的变量中
distList = lapply(....
)
您可以使用它轻松创建距离矩阵:
我们希望列和行的名称为 id
,让我们首先将 ID 分成两个向量,其中一个具有 sps == 0
,另一个具有 sps == 1
,幸运的是,我们通过创建 condition
向量做了一个很好的赌注:
Sps = data01$id[condition] %>% as.character
Nsps = data01$id[!condition] %>% as.character
现在我们创建矩阵,
matrix(nrow = sum(condition),ncol = sum(!condition))
我们并不真的需要 distList
中的所有数据,因此我们只 select sps == 1
或 sps == 0
中的数据,使用 0
更方便,我们通过将其转换为矩阵来覆盖我们的列表
:
distList = distList[!condition] %>%
do.call(what = "cbind")
现在我们将列和行命名为 school id
(请注意,我们保持初始列表的顺序对我们有很大帮助):
rownames(distList) = Sps
colnames(distList) = Nsps
就是这样...现在您应该能够查询任何一对 id
。例如:
distList["11725","11739"]
应该给你学校之间的距离
11725
和学校 11739
.
编辑 #2:
要查找关闭 sps == 0
学校到任何 sps == 1
学校,您可以执行以下操作:
distList = cbind(distList,
apply(distList,1,function(x){
x[which.min(x)]
})
我刚刚开始使用 R 和空间分析,所以我缺少很多基础知识!
我的数据包含学校地址。对于每所学校,我想计算到最近学校的距离。我的数据还包含有关 "special features" 所学校的信息。此变量 (sps) 编码为 1 ("with special features") 或 0 ("without special features")。我想计算从学校 "with special features" 到学校 "without special features" 的距离。这是我的数据的样子:
head(data01)
id lon lat sps
1 11725 6.932546 50.38269 0
2 11739 6.975160 50.48649 1
3 26883 6.987575 50.50857 0
到目前为止,我设法使用 st_distance 命令和以下代码计算到最近学校的距离。不幸的是,在使用此代码时,在某些情况下最近的学校都有 "special features"。我只想要从 1 -> 0 或 0 ->1 而不是 1->1!
的距离my_sf <- st_as_sf(data01,
coords = c("lon", "lat"), # x, y (order matters)
crs = 4326)
dist.mat <- st_distance(my_sf) # Great Circle distance since in lat/lon
# Number within 1.5km: Subtract 1 to exclude the point itself
num.1500 <- apply(dist.mat, 1, function(x) {
sum(x < 1500) - 1
})
# Calculate nearest distance
nn.dist <- apply(dist.mat, 1, function(x) {
return(sort(x, partial = 2)[2])
})
# Get index for nearest distance
nn.index <- apply(dist.mat, 1, function(x) { order(x, decreasing=F)[2] })
n.data <- data01
colnames(n.data)[1] <- "neighbor"
colnames(n.data)[2:ncol(n.data)] <-
paste0("n.", colnames(n.data)[2:ncol(n.data)])
mydata2 <- data.frame(data01,
n.data[nn.index, ],
n.distance = nn.dist,
radius1500 = num.1500)
rownames(mydata2) <- seq(nrow(mydata2))
感谢帮助!!
干杯,k
编辑:
我的最终数据集应该是这样的:
head(data01)
id lon lat sps dist
11725 6.932546 50.38269 0 xxxx
11739 6.975160 50.48649 1 xxxx
26883 6.987575 50.50857 0 xxxx
Dist 是到下一所学校的距离(0-> 1 或 1 -> 0)
二维欧几里德中两点之间距离的公式space(毕达哥拉斯):
sqrt( (x1-x2)**2 + (y1-y2)**2)
我们可以创建一个函数来计算它(您可以为 %>%
运算符调用 library(magrittr)
):
dist = function(x1,x2,y1,y2){
sqrt( (x1-x2)**2 + (y1-y2)**2) %>% return()
}
创建一个条件向量(不是强制性的,但它会使代码更具可读性。如果你知道如何,你可以直接内联条件)
condition = data01$sps %>% as.logical()
现在我们可以使用 lapply
:
lapply(1:nrow(data01), function(x){
if(condition[x]){
dist(data01$lon[!condition],
data01$lon[x],
data01$lat[!condition],
data01$lat[x])
}else{
dist(data01$lon[condition],
data01$lon[x],
data01$lat[condition],
data01$lat[x])
}
})
该代码未经测试,但它应该会生成一个向量列表,每个向量应该给出到具有相反 sps 值的学校的距离。第一个向量将对应于所有其他向量到它的距离等...
此解决方案还保留了邻居的顺序,这样向量中的第一个距离将始终对应于对面 sps 组的第一个邻居。
关于如何处理向量列表的问题,当然你可以将其作为列表保存到名为distList
:
distList = lapply(....
)
您可以使用它轻松创建距离矩阵:
我们希望列和行的名称为 id
,让我们首先将 ID 分成两个向量,其中一个具有 sps == 0
,另一个具有 sps == 1
,幸运的是,我们通过创建 condition
向量做了一个很好的赌注:
Sps = data01$id[condition] %>% as.character
Nsps = data01$id[!condition] %>% as.character
现在我们创建矩阵,
matrix(nrow = sum(condition),ncol = sum(!condition))
我们并不真的需要 distList
中的所有数据,因此我们只 select sps == 1
或 sps == 0
中的数据,使用 0
更方便,我们通过将其转换为矩阵来覆盖我们的列表
:
distList = distList[!condition] %>%
do.call(what = "cbind")
现在我们将列和行命名为 school id
(请注意,我们保持初始列表的顺序对我们有很大帮助):
rownames(distList) = Sps
colnames(distList) = Nsps
就是这样...现在您应该能够查询任何一对 id
。例如:
distList["11725","11739"]
应该给你学校之间的距离
11725
和学校 11739
.
编辑 #2:
要查找关闭 sps == 0
学校到任何 sps == 1
学校,您可以执行以下操作:
distList = cbind(distList,
apply(distList,1,function(x){
x[which.min(x)]
})