Использование purrr::map для получения нескольких столбцов в выходных данных

#r #purrr

#r #purrr

Вопрос:

Данные

У меня есть 2 набора данных:
* segments dataset представляет сегменты дороги ( lhrs .)
* hwys dataset представляет автомагистрали, которые содержат отдельные lhrs .

 > segments
# A tibble: 1 x 5
   lhrs mto_collision_ref_number latitude longitude highway_number
  <dbl>                    <dbl>    <dbl>     <dbl>          <dbl>
1 10004                  1549630     42.9     -78.9              1 


> hwys
# A tibble: 5 x 3
  STREET          longitude latitude
  <fct>               <dbl>    <dbl>
1 HIGHWAY 3           -80.0     42.9
2 ADELAIDE AVE E      -78.9     43.9
3 HOWARD AVE          -83.0     42.2
4 HIGHWAY 12          -79.7     44.7
5 CORONATION BLVD     -80.3     43.4
  

Проблема

Как вы можете видеть, STREET столбец отсутствует в segments наборе данных. Я хочу создать этот столбец в segments наборе данных, найдя расстояние между заданным lhrs и a STREET на основе значений долготы и широты. Это означает, что мне нужно сравнить один набор значений long, latt lhrs для всех 5 STREET местоположений и найти то, которое имеет минимальное расстояние. Я думаю, это можно сделать с помощью purrr package .

Мой код

Я могу найти расстояния между каждым из них, lhrs и STREET используя geosphere::distVincentyEllipsoid() расстояние следующим образом:

 library(tidyverse)



segments_nested <- segments %>% group_by(mto_collision_ref_number) %>% nest()


segments_nested %>% 
  mutate(diztances = purrr::map(
    data, ~ distVincentyEllipsoid(hwys %>% select(longitude, latitude),
                                             c(.$longitude, .$latitude)))) %>% 
  unnest(.preserve = data)


# A tibble: 5 x 3
  mto_collision_ref_number data             diztances
                     <dbl> <list>               <dbl>
1                  1549630 <tibble [1 x 4]>    85316.
2                  1549630 <tibble [1 x 4]>   110700.
3                  1549630 <tibble [1 x 4]>   342921.
4                  1549630 <tibble [1 x 4]>   213961.
5                  1549630 <tibble [1 x 4]>   125547.  
  

ОДНАКО я все еще не могу понять, как соединить эти расстояния с STREET . Пожалуйста, подскажите мне, как я могу использовать purrr::map для вычисления расстояний, А также соответствующих STREET . Как только у меня это будет, я могу просто group_by(mto_collision_ref_number) и получить summarize(min(diztances)) .

Комментарии:

1. Легче помочь, если вы используете dput для публикации своих данных

2. Передача вашего последнего набора кода в другой, unnest() вызванный без аргументов, получает фрейм данных ссылок, расстояний, а затем столбцов, составляющих содержимое data . Конечные размеры 5×6

3. @camille Это не включает STREET .

Ответ №1:

Один из способов добиться успеха — воспользоваться гибкостью анонимной функции и использовать ее для возврата объекта, который уже соответствует спецификации. Я использовал комбинацию group_by() и transmute() .

 # this is setup for transmute() so we keep 'STREET' around
hwys <- group_by(hwys, STREET) 

segments_nested %>%
  mutate(results = purrr::map(
    data, ~ transmute(hwys, diztances = geosphere::distVincentyEllipsoid(c(longitude, latitude),
                                             c(.$longitude, .$latitude))))) %>% 
  unnest(results)
  

И бинго, «УЛИЦА» снова в меню, ребята!

   mto_collision_ref_number STREET         diztances
                     <int> <chr>              <dbl>
1                  1549630 HIGHWAY3          89840.
2                  1549630 ADELAIDEAVEE     111101.
3                  1549630 HOWARDAVE        345569.
4                  1549630 HIGHWAY12        210099.
5                  1549630 CORONATIONBLVD   126702.
  

В будущем попробуйте предоставлять доступ к своим данным в более удобном для воспроизведения формате, я предпочитаю, read.table(text = ) но dput() также подойдет, как предложено выше. Мне пришлось копировать, вставлять и манипулировать вашим блоком вывода, чтобы поместить его в R:

 segments <- read.table(
  text = "lhrs mto_collision_ref_number latitude longitude highway_number
  1 10004 1549630 42.9 -78.9 1",
  header = T,
  stringsAsFactors = F
)
hwys <- read.table(
  text = "  STREET longitude latitude
  1 HIGHWAY3 -80.0 42.9
  2 ADELAIDEAVEE  -78.9 43.9
  3 HOWARDAVE -83.0 42.2
  4 HIGHWAY12 -79.7 44.7
  5 CORONATIONBLVD -80.3 43.4",
  header = T, 
  stringsAsFactors = F
)
  

Комментарии:

1. Большое спасибо! 1 для gif 🙂 Я не знаю почему, но вывод dput для этих данных был слишком длинным. Вероятно, это было связано с пространственной геометрической информацией. в данных.