[英]Calculating nearest distance to specific points using st_distance
我刚刚开始使用 R 和空间分析,所以我缺少很多基础知识!
我的数据包含学校地址。 对于每所学校,我想计算到最近学校的距离。 我的数据还包含有关学校“特色”的信息。 此变量 (sps) 编码为 1(“具有特殊功能”)或 0(“无特殊功能”)。 我想计算从“有特色”的学校到“没有特色”的学校的距离。 这是我的数据的样子:
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 命令和以下代码计算到最近学校的距离。 不幸的是,在使用此代码时,在某些情况下最近的学校都有“特殊功能”。 我只想要从 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)
二维欧氏空间(毕达哥拉斯)中两点之间的距离公式:
sqrt( (x1-x2)**2 + (y1-y2)**2)
我们可以创建一个 function 来计算它(您可以为%>%
运算符调用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
到 go 更方便,我们通过转换覆盖我们的列表它变成一个矩阵:
distList = distList[!condition] %>%
do.call(what = "cbind")
现在我们将我们的列和行命名为学校id
(请注意,我们在初始列表中保持顺序的事实在这里对我们有很大帮助):
rownames(distList) = Sps
colnames(distList) = Nsps
就是这样......现在你应该能够查询任何一对id
了。 例如: distList["11725","11739"]
应该给你学校11739
11725
的距离。
编辑#2:要找到关闭的sps == 0
学校到任何sps == 1
学校,您可以执行以下操作:
distList = cbind(distList,
apply(distList,1,function(x){
x[which.min(x)]
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.