Использование purrr :: map для получения нескольких столбцов в выводе - PullRequest
2 голосов
/ 19 марта 2019

Данные

У меня есть 2 набора данных:
* segments набор данных представляет сегменты дороги (lhrs.)
* hwys набор данных представляет магистрали, которые содержат отдельные 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 и STREET на основе значений долготы и широты.Это означает, что мне нужно сравнить один набор длинных лат lhrs со всеми 5 STREET местоположениями и найти тот, который имеет минимальное расстояние.Я думаю, что это можно сделать с помощью пакета purrr.

Мой код

Я могу найти расстояния между каждым 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 Ответ

1 голос
/ 20 марта 2019

Один из способов вернуться домой - воспользоваться гибкостью анонимной функции и использовать ее для возврата объекта, который уже имеет спецификацию.Я использовал комбинацию 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
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...