【问题标题】:How do I find the nearest location in a separate list of coordinates in r?如何在 r 的单独坐标列表中找到最近的位置?
【发布时间】:2021-09-18 04:53:12
【问题描述】:

给定一个活动地点列表:

event.coords <- data.frame(
    event.id = letters[1:5],
    lats = c(43.155, 37.804, 26.71, 35.466, 40.783),
    lons = c(-77.616,-122.271, -80.064, -97.513, -73.966))

以及地区的质心(恰好是邮政编码,但也可以是州、国家等):

locale.centroids <-
  data.frame(
    locale.id = 1:5,
    lats = c(33.449, 41.482, 40.778, 43.59, 41.736),
    lons = c(-112.074, -81.67, -111.888, -70.335, -111.834))

我想计算每个区域中心距最近事件的距离。我的数据包含 100,000 个语言环境,所以我需要一些计算效率高的东西。

【问题讨论】:

    标签: r geospatial sf sp rgeo


    【解决方案1】:

    tidyverse 策略。为了计算地理距离,我使用包geosphere

    event.coords <- data.frame(
      event.id = letters[1:5],
      lats = c(43.155, 37.804, 26.71, 35.466, 40.783),
      lons = c(-77.616,-122.271, -80.064, -97.513, -73.966))
    
    locale.centroids <-
      data.frame(
        locale.id = 1:5,
        lats = c(33.449, 41.482, 40.778, 43.59, 41.736),
        lons = c(-112.074, -81.67, -111.888, -70.335, -111.834))
    
    library(tidyverse)
    library(geosphere)
    
    event.coords %>% rowwise() %>%
      mutate(new =  map(list(c(lons, lats)), ~ locale.centroids %>% rowwise() %>%
                          mutate(dist = distGeo((c(lons, lats)), .x)) %>%
                          ungroup %>%
                          filter(dist == min(dist)) %>%
                          select(locale.id, dist)))  %>%
      ungroup() %>% unnest_wider(new)
    
    #> # A tibble: 5 x 5
    #>   event.id  lats   lons locale.id     dist
    #>   <chr>    <dbl>  <dbl>     <int>    <dbl>
    #> 1 a         43.2  -77.6         2  382327.
    #> 2 b         37.8 -122.          3  953915.
    #> 3 c         26.7  -80.1         2 1645206.
    #> 4 d         35.5  -97.5         1 1355234.
    #> 5 e         40.8  -74.0         4  432562.
    

    reprex package (v2.0.0) 于 2021-07-07 创建

    【讨论】:

    • 优雅,对于任何熟悉 tidyverse 的人来说都易于理解。不幸的是,不能很好地扩展到大型数据集
    【解决方案2】:

    将两个数据框转换为sf 对象后,您可以使用sf::st_nearest_feature 匹配最近的点特征,并使用sf::st_distance 找出距离值。

    sf 包在我使用的数据集上的速度非常好,但它们确实小于 100k。根据数据的存储方式,您可以研究像 postGIS 这样的数据库方法。

    library(sf)
    
    event.coords.sf <- st_as_sf(event.coords, coords = c('lons', 'lats'), crs = 'EPSG: 4326')
    locale.centroids.sf <- st_as_sf(locale.centroids, coords = c('lons', 'lats'), crs = 'EPSG: 4326')
    
    
    nearest_id <- st_nearest_feature(event.coords.sf, locale.centroids.sf)
    
    nearest_dist <- st_distance(event.coords.sf, 
                                locale.centroids.sf[nearest_id,], 
                                by_element = TRUE)
    
    cbind(event.coords, nearest_id, nearest_dist)
    #---
      event.id   lats     lons nearest_id  nearest_dist
    1        a 43.155  -77.616          2  382326.7 [m]
    2        b 37.804 -122.271          3  953914.6 [m]
    3        c 26.710  -80.064          2 1645205.7 [m]
    4        d 35.466  -97.513          1 1355233.5 [m]
    5        e 40.783  -73.966          4  432561.5 [m]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      相关资源
      最近更新 更多