根据经纬度获取K个最近邻

Get K nearest neighbors based on latitude and longitude

我有不同点的纬度和经度数据。这是我的数据的简单版本:

# Add library
library(tidyverse)

# Generate data
distance <-
  tibble(
    location = c("first", "second", "third"),
    lat = c(33.720792, 33.715187, 33.714848),
    long = c(-84.468126, -84.468684, -84.454265)
  ) 

生成的数据如下所示:

# A tibble: 3 x 3
  location   lat  long
  <chr>    <dbl> <dbl>
1 first     33.7 -84.5
2 second    33.7 -84.5
3 third     33.7 -84.5

我想做的是利用这些纬度和经度来获得每个位置的最近邻居的完整排名。例如,理想情况下我的最终数据应该是这样的:

如您所见,此新数据框中的第一列包含位置“first”的第一个最近邻,第二列提供下一个最近邻,依此类推。

有谁知道如何制作我需要的数据框?

geodist 中的 geodist 函数计算经纬度指定的点之间的距离,即

library(geodist)
geodist(distance)

#          [,1]      [,2]     [,3]
#[1,]    0.0000  625.0321 1441.547
#[2,]  625.0321    0.0000 1333.401
#[3,] 1441.5466 1333.4007    0.000

然后可以按行对这些进行排序以提供输出

apply(geodist::geodist(distance),1,function(x)distance$location[order(x)])
#     [,1]     [,2]     [,3]    
#[1,] "first"  "second" "third" 
#[2,] "second" "first"  "second"
#[3,] "third"  "third"  "first" 

如果需要,可以使用 data.frame() 和设置 colnames.

根据需要格式化输出

如果可能存在重复,您需要从排序中明确排除前导对角线,并从输入数据中复制 location 列。

您可以使用 FNN 包来查找 k 最近邻。它可以很好地处理大量数据,因此即使是大型数据集,您也应该能够使用以下代码找到完整排名:

# Add library
library(tidyverse)
library(FNN)
#> Warning: pakke 'FNN' blev bygget under R version 4.0.4

# Generate data
distance <-
  tibble(
    location = c("first", "second", "third"),
    lat = c(33.720792, 33.715187, 33.714848),
    long = c(-84.468126, -84.468684, -84.454265)
  ) 

# Find KNN
knn <- distance %>% 
  select(lat,long) %>% 
  get.knn(k = nrow(.) - 1)

knn
#> $nn.index
#>      [,1] [,2]
#> [1,]    2    3
#> [2,]    1    3
#> [3,]    2    1
#> 
#> $nn.dist
#>             [,1]       [,2]
#> [1,] 0.005632707 0.01508173
#> [2,] 0.005632707 0.01442298
#> [3,] 0.014422985 0.01508173

# Identify locations
loc <- knn$nn.index
loc[] <- distance$location[loc]
colnames(loc) <- paste0("neighbour_",1:ncol(loc))

loc
#>      neighbour_1 neighbour_2
#> [1,] "second"    "third"    
#> [2,] "first"     "third"    
#> [3,] "second"    "first"

# final data
distance %>% 
  select(location) %>% 
  bind_cols(loc %>% as_tibble())
#> # A tibble: 3 x 3
#>   location neighbour_1 neighbour_2
#>   <chr>    <chr>       <chr>      
#> 1 first    second      third      
#> 2 second   first       third      
#> 3 third    second      first

reprex package (v0.3.0)

于 2021-03-25 创建