这是一种使用 sp 类对象的方法。您可以使用以下方式将 data.frame 对象强制转换为 SpatialPointsDataFrame 对象:coordinates(x) <- ~lon+lat 这里的想法是派生两个点要素类之间的距离矩阵,然后根据列名提取距离和 ID(分配自学校数据)。这不仅会返回距离,而且还会返回每所学校的唯一标识符,从而可以轻松查询与任何给定属性特征最近的实际学校。
首先,添加所需的库并创建一些示例数据。
library(sp)
library(raster)
e <- as(raster::extent(-180, 180, -90, 90), "SpatialPolygons")
properties <- spsample(e, 1000, type="random")
proj4string(properties) <- "+proj=longlat +ellps=WGS84"
schools <- spsample(e, 100, type="random")
proj4string(schools) <- "+proj=longlat +ellps=WGS84"
schools$ids <- paste0("school", 1:length(schools))
现在,我们可以创建距离矩阵,将对角线分配给 NA,并将学校的唯一标识符添加到矩阵的列名。
d <- spDists(x = properties, y = schools, longlat = TRUE)
diag(d) <- NA
colnames(d) <- schools$ids
当然有更优雅的方法可以做到这一点,但为了简单起见,我们将使用一个 for 循环来填充代表距离和 ID 的两个向量。我们使用which.min 将索引拉到第 i 行的最小距离。迭代器基于矩阵行,因为它们代表属性特征。
sdist <- rep(NA, nrow(d))
sid <- rep(NA, nrow(d))
for(i in 1:nrow(d)) {
srow <- d[i,]
sdist[i] <- srow[which.min(srow)]
sid[i] <- names(srow)[which.min(srow)]
}
然后我们可以将结果向量分配给属性 SpatialPointsDataFrame。现在我们在 @data 槽 data.frame 中有列,表示到最近学校的距离以及学校 ID。
properties$school <- sid
properties$dist <- sdist
在这里我们可以绘制结果。
par(mfrow=c(2,1))
plot(properties, pch=19, cex=0.5)
plot(schools, pch=19, col="red", add=TRUE)
plot(e, add=TRUE)
title("random properties (black) and schools (red)", cex=0.5)
plot(properties, col="white")
plot(properties[1,], pch=19, cex=2, add=TRUE)
plot(schools[which(schools$ids %in% properties[1,]$school),],
pch=19, cex=2, col="red", add=TRUE)
plot(e, add=TRUE)
title("Property 1 (black) and closest school (red)", cex=0.5)
sidx <- which(schools$ids %in% properties[1,]$school)
text(coordinates(schools[sidx,]),
label = schools[sidx,]$ids, col="blue", cex=1)