Условное извлечение нескольких подстрок и возвращение значения для каждой подстроки с использованием цикла for - PullRequest
0 голосов
/ 14 мая 2018

Я хотел бы найти элегантный подход к:

  1. Использовать цикл for каждый уникальный элемент в 'zone'
  2. , чтобы извлечь несколько подстрок из 'country_name' каждаястрока в df1
  3. сохранить несколько подстрок для каждой зоны / строки как вектор или список для следующего шага
  4. вернуть значение для каждого вектора зоны / строки в df1 для уникального элемента подстрокипринадлежит с помощью df2.
  5. Результирующий вывод будет выглядеть как df3

У меня есть два кадра данных:

Первый data.frame:

zone = c("A", "B", "C")
country_name = c("Canada and UK", "UK and USA", "USA and Canada and UK") 
df1 = data.frame(zone, country_name)

Вторые данные.frame:

zone_area = c("A", "A", "A", "B", "B", "B", "C", "C", "C")
country_name = c("Canada", "UK", "USA", "Canada", "UK", "USA", "Canada", "UK", "USA")
cost = c(4, 8, 6, 5, 6, 9, 8, 7, 5)
df2 = data.frame(zone_area, country_name, cost)

Окончательный результирующий data.frame должен выглядеть как df3:

zone = c("A", "B", "C")
country_name = c("Canada and UK", "UK and USA", "USA and Canada and UK")
cost = c(12, 15, 20)
df3 = data.frame(zone, country_name, cost)

Причина, по которой мне нужно использовать цикл forпотому что код должен работать, если используются разные значения зоны.

Спасибо всем, кто просматривает этот вопрос и может предоставить метод для работы:)

1 Ответ

0 голосов
/ 14 мая 2018

Мы могли бы left_join после разделения 'country_name' на 'и', сгруппированных по 'zone', получить sum of 'cost' и сделать right_join с исходным набором данных, чтобы получить ожидаемый результат

library(tidyverse)
df1 %>% 
   separate_rows(country_name, sep="\\s+and\\s+") %>%
   left_join(df2) %>% 
   group_by(zone) %>% 
   summarise(cost = sum(cost)) %>% 
   right_join(df1) %>%
   select(zone, country_name, cost)
# A tibble: 3 x 3
#  zone  country_name           cost
#   <fct> <fct>                 <dbl>
#1 A     Canada and UK            12
#2 B     UK and USA               15
#3 C     USA and Canada and UK    20

Или вместо использования separate_rows мы делаем left_join, а затем filter на основе шаблона в 'country_name', получаем sum из 'cost' и right_join с 'df1'

left_join(df2, df1, by = "zone") %>%
    group_by(zone) %>% 
    filter(grepl(gsub("\\s*and\\s*", "|", country_name.y[1]), country_name.x)) %>%
    summarise(cost = sum(cost)) %>%
    right_join(df1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...