сделайте нечеткое соединение и сохраните только точное совпадение, если оно есть, в противном случае оставьте все параметры - PullRequest
0 голосов
/ 06 августа 2020

У меня есть два фрейма данных, к которым я пытаюсь присоединиться на основе поля названия страны, и я хотел бы достичь следующего: когда будет найдено идеальное совпадение, я хотел бы сохранить только эту строку, в противном случае я бы хотел показать все строки / параметры.

library(fuzzyjoin)

df1 <- data.frame(
  country = c('Germany','Germany and Spain','Italy','Norway and Sweden','Austria','Spain'),
  score = c(7,8,9,10,11,12)
)

df2 <- data.frame(
  country_name = c('Germany and Spain','Germany','Germany.','Germania','Deutschland','Germany - ','Spun','Spain and Portugal','Italy','Italia','Greece and Italy',
                   'Australia','Austria...','Norway (Scandinavia)','Norway','Sweden'),
  comments = c('xxx','rrr','ttt','hhhh','gggg','jjjj','uuuuu','ooooo','yyyyyyyyyy','bbbbb','llllll','wwwwwww','nnnnnnn','cc','mmmm','lllll')
)

j <- regex_left_join(df1,df2, by = c('country' = 'country_name'), ignore_case = T)

Результаты (j) показывают, что «Германия и Испания» появляются 3 раза, первое вхождение - идеальное совпадение, я хотел бы оставить только этот и избавиться от другие два. «Норвегия и Швеция» не имеют идеального соответствия, поэтому я хотел бы сохранить два возможных варианта / строки (как есть).

Как я могу это сделать?

1 Ответ

0 голосов
/ 06 августа 2020

Вы можете использовать stringdist::stringdist для вычисления расстояния между совпадениями, а для записей, где существует точное совпадение, оставьте только это:

library(dplyr)
j %>% 
  mutate(dist = stringdist::stringdist(country, country_name)) %>% # add distance
  group_by(country) %>%                                            # group entries
  mutate(exact = any(dist == 0)) %>%                               # check if exact match exists in group
  filter(!exact | dist == 0) %>%                                   # keep only entries where no exact match exists in the group OR where the entry is the exact match
  ungroup()
#> # A tibble: 5 x 6
#>   country           score country_name      comments    dist exact
#>   <chr>             <dbl> <chr>             <chr>      <dbl> <lgl>
#> 1 Germany               7 Germany           rrr            0 TRUE 
#> 2 Germany and Spain     8 Germany and Spain xxx            0 TRUE 
#> 3 Italy                 9 Italy             yyyyyyyyyy     0 TRUE 
#> 4 Norway and Sweden    10 Norway            mmmm          11 FALSE
#> 5 Norway and Sweden    10 Sweden            lllll         11 FALSE
...