在R中使用`mutate_at`或`map`函数来计算多个位置之间的距离

问题描述

我在数据框(controids)上具有一组位置的经度和纬度:

library(tidyverse)

centroids <- 
  tribble(
    ~city,~long,~lat,"A",-89.92702,44.19367,"B",-89.92525,44.19654,"C",-89.92365,44.19756,"D",-89.91949,44.19848,"E",-89.91359,44.19818) 

我有第二个数据框(towns),其中包含第二组位置的经度和纬度。

towns <- 
  tribble(
    ~town,"greentown",-89.92225,44.19727,"bluetown",-89.92997,44.19899,"redtown",-89.91500,44.19600)

我想在centroids添加三列,以给出每个城市与towns中三个城镇中每个城镇之间的直线距离(以公里为单位)。因此,最终数据帧将如下所示(距离不正确,仅用于说明):

output <- 
  tribble(
    ~city,~greentown_dist,~bluetown_dist,~redtown_dist,5.3,2.0,1.2,4.4,2.3,9.9,3.7,5.4,3.3,2.6,3.9,6.7,44.19818,10.2,2.2,3.1)

我必须在许多城镇中执行此操作,因此我试图编写一些易于推广的代码。这是我到目前为止所拥有的。

library(sf)

towns <- towns %>% st_as_sf(.,coords=c('long','lat')) %>% st_geometry()

output <- 
  centroids %>% 
  st_as_sf(.,'lat')) %>% 
  mutate(greentown_dist = st_distance(geometry,st_point(c( unlist(towns[1]) ))),bluetown_dist = st_distance(geometry,st_point(c( unlist(towns[2]) ))),redtown_dist = st_distance(geometry,st_point(c( unlist(towns[3]) ))))

我想知道是否有一种方法可以使用mutate_at和/或purrr map函数-一种自动填写TOWN_dist列名并输入正确行的函数来自town数据框。

解决方法

我们可以使用map遍历“城镇”

centroids[paste0(c("green","blue","red"),"town_dist")] <- map(towns,~ centroids %>% 
            st_as_sf(.,coords = c('long','lat')) %>%
            transmute(dist = st_distance(geometry,st_point(c( unlist(.x))))))