мурлыкать, чтобы найти наименьшее значение, а затем пометить case_when - PullRequest
3 голосов
/ 19 июня 2019

У меня есть два набора данных.Первый содержит список городов и их расстояние в милях от пунктов назначения.Второй список содержит места назначения.Я хочу использовать purrr, чтобы поместить имя ближайшего пункта назначения в новый столбец в первом наборе данных.

Вот первый набор данных (с составленными данными / расстояниями):

library(tidyverse)
data1 <- tibble(city = c("Atlanta", "Tokyo", "Paris"),
                   dist_Rome = c(1000, 2000, 300),
                   dist_Miami = c(400, 3000, 1500),
                   dist_Singapore = c(3000, 600, 2000),
                   dist_Toronto = c(900, 3200, 1900))

Вот второй набор данных с пунктами назначения:

library(tidyverse)
data2 <- tibble(destination = c("Rome Italy", "Miami United States", "Singapore Singapore", "Toronto Canada"))

И вот как я хочу, чтобы он выглядел следующим образом:

library(tidyverse)
solution <- tibble(city = c("Atlanta", "Tokyo", "Paris"),
                   dist_Rome = c(1000, 2000, 300),
                   dist_Miami = c(400, 3000, 1500),
                   dist_Singapore = c(3000, 600, 2000),
                   dist_Toronto = c(900, 3200, 1900),
                   nearest = c("Miami United States", "Singapore Singapore", "Rome Italy"))

В идеале я ищу подходящее решение, и я попыталсясделать это с мурлыканием, но безрезультатно.Это моя неудачная попытка:

library(tidyverse)
solution <- data1 %>%
  mutate(nearest_hub = map(select(., contains("dist")), ~
                                  case_when(which.min(c(...)) ~ data2$destination),
                                TRUE ~ "NA"))
Error in which.min(c(...)) : 
  (list) object cannot be coerced to type 'double'

Спасибо!

Ответы [ 2 ]

2 голосов
/ 19 июня 2019

Решение с использованием tidyverse.

library(tidyverse)

data3 <- data1 %>%
  mutate(City = apply(data1 %>% select(-city), 1, function(x) names(x)[which.min(x)])) %>%
  mutate(City = str_remove(City, "^dist_")) %>%
  left_join(data2 %>%
              separate(destination, into = c("City", "Country"), sep = " ", remove = FALSE),
            by = "City") %>%
  select(-City, -Country) %>%
  rename(nearest = destination)

data3
# # A tibble: 3 x 6
#   city    dist_Rome dist_Miami dist_Singapore dist_Toronto nearest            
#   <chr>       <dbl>      <dbl>          <dbl>        <dbl> <chr>              
# 1 Atlanta      1000        400           3000          900 Miami United States
# 2 Tokyo        2000       3000            600         3200 Singapore Singapore
# 3 Paris         300       1500           2000         1900 Rome Italy
2 голосов
/ 19 июня 2019

Мы можем gather в «длинный» формат, сгруппированный по «городу», slice строки с минимальным «val», left_join с «data2», чтобы получить «ближайший»

library(tidyverse)
data1 %>% 
   gather(key, val, starts_with("dist")) %>% 
   group_by(city) %>% 
   slice(which.min(val)) %>% 
   ungroup %>%
   transmute(city, key = str_remove(key, 'dist_')) %>% 
   left_join(data2 %>% 
   mutate(key = word(destination, 1))) %>%
   select(city, nearest = destination) %>% 
   left_join(data1)
...