Как искать и извлекать совпадающие слова из другого столбца в кадре данных? - PullRequest
0 голосов
/ 31 января 2019

У меня есть переменная в кадре данных с именем поля 'Destination'.Это поле содержит пункт назначения / места (может быть страна, континент, несколько стран, города, город и т. Д. Или оба).У меня есть другой фрейм данных, который содержит 3 столбца continent_name, country_name, city_name и т. Д. Я хочу получить новый столбец с именами континентов, стран, городов, сопоставив поле назначения с 2 столбцами dataframe.

Фрейм данных A:

+---------+------------------------------------+
|  Name   |            Destination             |
+---------+------------------------------------+
| Alex    | North America, Europe & France     |
| Mike    | Boston, London, Germany, Australia |
| Charlie | China, Europe, India, New York     |
| Lophy   | Antartica, UK, Europe, Delhi       |
+---------+------------------------------------+

Фрейм данных B:

---------------+-----------+----------+
|   Continent   |  Country  |   City   |
+---------------+-----------+----------+
| north america | france    | boston   |
| anatartica    | germany   | london   |
| europe        | australia | delhi    |
| XYZ           | china     | new york |
| ABC           | india     | RST      |
| PQR           | UK        | JKL      |
+---------------+-----------+----------+

Ожидаемый результат:

+---------+-----------------------+--------------------+----------------+
|  Name   |       Continent       |      Country       |      City      |
+---------+-----------------------+--------------------+----------------+
| Alex    | North America, Europe | France             |                |
| Mike    | NA                    | Germany, Australia | Boston, London |
| Charlie | Europe                | China, India       | New York       |
| Lophy   | Antartica, Europe     | UK                 | Delhi          |
+---------+-----------------------+--------------------+----------------+

Сначала должны совпадать имена всех континентов ихранится в виде значений, разделенных запятыми, в случае нескольких совпадений, затем названий стран, а затем названий городов.

Я прошел через несколько вопросов, но не смог получить ничего конкретного.

Ответы [ 3 ]

0 голосов
/ 31 января 2019

Самое простое - поместить обе таблицы в длинный формат и соединить их, а затем вернуться к широкоформатному формату, используя тип назначения:

library(tidyverse)
B2 <- B %>% 
  gather(type,lower_dest) %>%
  mutate_at("lower_dest", tolower)

A2 <- A %>% 
  separate_rows(Destination,sep="\\s*[,&]\\s*") %>%
  mutate(lower_dest = tolower(Destination))

left_join(A2, B2, by = "lower_dest") %>%
  group_by(Name, type) %>%
  summarize_at("Destination", paste,collapse=", ") %>%
  spread(type, Destination) %>%
  ungroup

# # A tibble: 4 x 4
#      Name           City             Continent            Country
# *   <chr>          <chr>                 <chr>              <chr>
# 1    Alex           <NA> North America, Europe             France
# 2 Charlie       New York                Europe       China, India
# 3   Lophy          Delhi     Antartica, Europe                 UK
# 4    Mike Boston, London                  <NA> Germany, Australia

data

A <-
  tribble(~Name   , ~Destination ,   
 'Alex'    , 'North America, Europe & France',     
 'Mike'    , 'Boston, London, Germany, Australia', 
 'Charlie' , 'China, Europe, India, New York', 
 'Lophy'   , 'Antartica, UK, Europe, Delhi')     


# anatartica typo corrected into antartica  
B <- tribble(~Continent, ~Country, ~City,
 'north america' , 'france'    , 'boston'   ,
 'antartica'    , 'germany'   , 'london'   ,
 'europe'        , 'australia' , 'delhi'    ,
 'XYZ'           , 'china'     , 'new york' ,
 'ABC'           , 'india'     , 'RST'      ,
 'PQR'           , 'UK'        , 'JKL')
0 голосов
/ 31 января 2019
# data
d <- read.table(text = "Name Destination
Alex 'North America, Europe & France'
Mike 'Boston, London, Germany, Australia'
Charlie 'China, Europe, India, New York'
Lophy 'Antartica, UK, Europe, Delhi'",
                header = TRUE,
                stringsAsFactors = FALSE)
d$Destination <- gsub("&", ",", d$Destination)
d$Destination <- tolower(d$Destination)
d$Destination <- trimws(d$Destination)
d

d2 <- read.table(text = " Continent  Country City
'north america' france boston
anatartica  germany london
europe australia delhi
XYZ china 'new york' 
ABC india RST
PQR UK  JKK", header = TRUE, stringsAsFactors = FALSE)
d2

# splits ..
check_fun <- function(a, b) {
  toString(intersect(trimws(strsplit(d$Destination[a], ",")[[1]], "both"), d2[[b]]))
}

want <- as.data.frame(do.call(cbind,
                              lapply(colnames(d2),
                                     function(x) {
                                       sapply(seq_along(d$Destination),
                                              function(y) {
                                                check_fun(y, x)
                                              }
                                              )
                                       })), stringsAsFactors = FALSE)
colnames(want) <- colnames(d2)
want$Name <- d$Name
want                              

# Continent            Country           City    Name
# 1 north america, europe             france                   Alex
# 2                       germany, australia boston, london    Mike
# 3                europe       china, india       new york Charlie
# 4                europe                             delhi   Lophy  
0 голосов
/ 31 января 2019

Несколько функций, которые вам помогут:

tolower() переведет все ваши слова в нижний регистр, чтобы у вас были совпадения, когда есть сочетание заглавных букв.str_split() из stringr позволит вам разделить пункты назначения на элементы, разделенные запятыми

Итак, сначала вам нужно получить вектор со всеми пунктами назначения:

destination_vector <-unique(unlist(strsplit(tolower(Destination), ","))),Поскольку strsplit дает вам список, вам нужно unlist, чтобы получить вектор.unique получит удаление дубликатов, если таковые имеются.

Затем вам необходимо проверить, находится ли какой-либо из ваших пунктов назначения на континенте, в стране или городе:

Continent[Continent %in% destination_vector].То же самое для страны и города

Затем вы можете использовать paste с sep=",", чтобы объединить все, используя запятые в качестве разделителя.

Best!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...