我有两个不同电台的数据集。数据基本上是具有坐标,经度和纬度的数据框架。给定第一个数据集(反之亦然),我想找到其他数据集中每个站的最近站。我的主要问题是坐标没有排序,数据集的长度不同。例如,第一个包含2228个站点,第二个包含1782个站点。因此,我不知道如何处理这个问题。 我知道函数rdist.earth,我试图使用它。这是一个简短的例子:
#First data set of stations
set1 <- structure(list(lon = c(13.671114, 12.866947, 15.94223, 11.099736,
12.958342, 14.203892, 11.86389, 16.526674, 16.193064, 17.071392
), lat = c(48.39167, 48.148056, 48.721111, 47.189167, 47.054443,
47.129166, 47.306667, 47.84, 47.304167, 48.109444)), .Names = c("lon",
"lat"), row.names = c(NA, 10L), class = "data.frame")
#Second data set
set2 <- structure(list(lon = structure(c(14.4829998016357, 32.4000015258789,
-8.66600036621094, 15.4670000076294, 18.9160003662109, 19.0160007476807,
31.0990009307861, 14.3660001754761, 9.59899997711182, 11.0830001831055
), .Dim = 10L), lat = structure(c(35.8499984741211, 34.75, 70.9329986572266,
78.25, 69.6829986572266, 74.515998840332, 70.3659973144531, 67.265998840332,
63.6990013122559, 60.1990013122559), .Dim = 10L)), .Names = c("lon",
"lat"), row.names = c(NA, 10L), class = "data.frame")
#computing distance
dd<- rdist.earth(set1,set2,miles=FALSE)
现在我有矩阵dd,距离......但我不知道如何找到每个点的信息。我的意思是,例如,从数据集1,第一点,第二个数据集中最近的站点是什么?有什么想法??
非常感谢。
答案 0 :(得分:15)
这是另一种可能的解决方案:
library(rgeos)
set1sp <- SpatialPoints(set1)
set2sp <- SpatialPoints(set2)
set1$nearest_in_set2 <- apply(gDistance(set1sp, set2sp, byid=TRUE), 1, which.min)
head(set1)
lon lat nearest_in_set2
## 1 13.67111 48.39167 10
## 2 12.86695 48.14806 10
## 3 15.94223 48.72111 10
## 4 11.09974 47.18917 1
## 5 12.95834 47.05444 1
## 6 14.20389 47.12917 1
答案 1 :(得分:4)
您可以使用一系列apply命令来执行此操作。注意,函数中的x和y指的是set1和set2而不是lat lon coords - lat lon coords指定为p1和p2。 [注意:编辑在计算中更正set1和set2的顺序 - 顺序确定您是否计算最接近集合1中每个值的set2中的值,反之亦然)
distp1p2 <- function(p1,p2) {
dst <- sqrt((p1[1]-p2[1])^2+(p1[2]-p2[2])^2)
return(dst)
}
dist2 <- function(y) min(apply(set2, 1, function(x) min(distp1p2(x,y))))
apply(set1, 1, dist2)
或者,如果你想让站点距离最近点而不是最小距离改变min,那么.min in dist2()
dist2b <- function(y) which.min(apply(set2, 1, function(x) min(distp1p2(x,y))))
apply(set1, 1, dist2b)
获得该站的lat-lon
set2[apply(set1, 1, dist2b),]
答案 2 :(得分:3)
如果您有非常大的数据集,使用距离命令可能很麻烦,因为它必须计算参考数据中每个点的替代数据中所有点的距离。 &#39; ann&#39;来自&#39; yaImpute&#39; package是一个非常快速的近似最近邻程序,适用于大距离计算。然而,它会返回许多最近的&#34;你想要的记录(k的值)以及每个记录的距离。
注意:尽管是近似最近邻居,但结果在重复运行相同数据时仍然稳定。它不包括随机选择的点或任何东西。见文档。
FWIW,我真的不是在开玩笑。我用这个来找到两个矩阵的knn距离,每个矩阵有数百万个点。为此制作距离矩阵或逐行迭代地执行它是不可行或缓慢的。
快速举例:
# Hypothetical coordinate data
set.seed(2187); foo1 <- round(abs(data.frame(x=runif(5), y=runif(5))*100))
set.seed(2187); foo2 <- round(abs(data.frame(x=runif(10), y=runif(10))*100))
foo1; foo2
# the 'ann' command from the 'yaImpute' package
install.packages("yaImpute")
library(yaImpute)
# Approximate nearest-neighbour search, reporting 2 nearest points (k=2)
# This command finds the 3 nearest points in foo2 for each point in foo1
# In the output:
# The first k columns are the row numbers of the points
# The next k columns (k+1:2k) are the *squared* euclidean distances
knn.out <- ann(as.matrix(foo2), as.matrix(foo1), k=3)
knn.out$knnIndexDist
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 5 4 729 1658 2213
[2,] 2 3 7 16 100 1025
[3,] 9 7 5 40 81 740
[4,] 4 1 6 16 580 673
[5,] 5 7 9 0 677 980
答案 3 :(得分:0)
我并不完全知道你想要什么,但也许这会给你一些提示 如果你想获得每列的最小值
dd <- as.data.frame(dd)
sapply(dd, min)
paste(rownames(dd), ":", apply(dd,2,which.min)) #or
答案 4 :(得分:0)
s2包中的函数s2_closest_feature()从不同的数据集中查找最近的点。
例如,使用您的数据:
library(s2)
set1_s2 <- s2_lnglat(set1$lon, set1$lat)
set2_s2 <- s2_lnglat(set2$lon, set2$lat)
set1$closest <- s2_closest_feature(set1_s2, set2_s2)
set1
#> lon lat closest
#> 1 13.67111 48.39167 10
#> 2 12.86695 48.14806 10
#> 3 15.94223 48.72111 10
#> 4 11.09974 47.18917 1
#> 5 12.95834 47.05444 1
#> 6 14.20389 47.12917 1
#> 7 11.86389 47.30667 1
#> 8 16.52667 47.84000 1
#> 9 16.19306 47.30417 1
#> 10 17.07139 48.10944 1