在R中使用需要四个向量的函数进行迭代

时间:2019-06-05 13:24:41

标签: r iteration purrr pmap geosphere

我正在尝试使用geosphere软件包中的distHaversine函数查找多个城市之间的距离。这段代码需要各种参数:

首位的经度和纬度。 第二位的经度和纬度。 地球半径以任何单位表示(我使用r = 3961表示英里)。

当我将其输入为向量时,它很容易工作:

HongKong <- c(114.17, 22.31)
GrandCanyon <- c(-112.11, 36.11)

library(geosphere)
distHaversine(HongKong, GrandCanyon, r=3961)
#[1] 7399.113 distance in miles

但是,我的实际数据集如下:

library(dplyr)
location1 <- tibble(person = c("Sally", "Jane", "Lisa"),
current_loc = c("Bogota Colombia", "Paris France", "Hong Kong China"),
lon = c(-74.072, 2.352, 114.169),
lat = c(4.710, 48.857, 22.319))

location2 <- tibble(destination = c("Atlanta United States", "Rome Italy", "Bangkok Thailand", "Grand Canyon United States"),
              lon = c(-84.388, 12.496, 100.501, -112.113),
              lat = c(33.748, 41.903, 13.756, 36.107))

我想要的是要有行,说明每个目的地距该人当前位置的距离。

我知道必须使用purrr的pmap_dbl(),但我无法弄清楚。

如果您的代码使用tidyverse,以及是否有任何简单的方法可以使列标识最接近的目标,则奖励点。谢谢!

在理想的世界中,我会得到这个:

solution <- tibble(person = c("Sally", "Jane", "Lisa"),
                    current_loc = c("Bogota Colombia", "Paris France", "Hong Kong China"),
                    lon = c(-74.072, 2.352, 114.169),
                    lat = c(4.710, 48.857, 22.319),
                   dist_Atlanta = c(1000, 2000, 7000),
                   dist_Rome = c(2000, 500, 3000),
                   dist_Bangkok = c(7000, 5000, 1000),
                   dist_Grand = c(1500, 4000, 7500),
                   nearest = c("Atlanta United State", "Rome Italy", "Bangkok Thailand"))

注意:dist列中的数字是随机的;但是,它们将是distHaversine()函数的输出。这些列的名称是任意的-不必这样命名。另外,如果最接近的列不在此问题的范围内,我想我可以算出那个。

2 个答案:

答案 0 :(得分:2)

@Bean @Override public UserDetailsService userDetailsService() { UserDetails user = User.withDefaultPasswordEncoder() .username("u") .password("p") .roles("USER") .build(); return new InMemoryUserDetailsManager(user); } 一次仅接受一对lat和lon值,因此我们需要将distHaversinelocation1行的所有组合一一发送给该函数。使用location2的一种方法是

sapply

答案 1 :(得分:1)

根据您的要求,使用tidyversemap函数形式purrr,我找到了一个解决方案,全部在一条管道上。

library(tidyverse)
library(geosphere)

# renaming lon an lat variables in each df

location1 <- location1 %>%
 rename(lon.act = lon, lat.act = lat)

location2 <- location2 %>%
  rename(lon.dest = lon, lat.dest = lat)

# geting distances
merge(location1, location2, all = TRUE) %>%
  group_by(person,current_loc, destination) %>%
  nest() %>%
  mutate( act = map(data, `[`, c("lon.act", "lat.act")) %>%
            map(as.numeric),
          dest = map(data, `[`, c("lon.dest", "lat.dest")) %>%
            map(as.numeric),
          dist = map2(act, dest, ~distHaversine(.x, .y, r = 3961))) %>%
  unnest(data, dist) %>%
  group_by(person) %>%
  mutate(mindis = dist == min(dist))