R: "vlookup" на основе частичных совпадений строк в R - PullRequest
1 голос
/ 10 марта 2020

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

1,

             NAME
1         SMALL H
2          ZITT M
3         SMITH E
4       GLANZEL W
5        HUANG MH
6         THIJS B

и 2,

name                                    address
SIBLEY B                                SOME ADDRESS 1
STEWART C;KOCH A                        SOME ADDRESS 2
HILL GM;LEE A;SMITH E                   SOME ADDRESS 3
DAVIS L                                 SOME ADDRESS 4
MERCIER K;SMITH E;GIBBONE A             SOME ADDRESS 5
DAVIDSON S;BEKIARI A                    SOME ADDRESS 6

Я хочу быть в состоянии соответствовать NAME в пределах 1-ая таблица для случаев, когда во 2-й таблице есть совпадение строк с name, а затем добавляются данные из столбца ADDRESS, что немного похоже на vlookup. Он также должен иметь дело с несколькими экземплярами одного и того же имени. В приведенном выше примере имя SMITH E (разные люди) будет соответствовать, что даст следующий результат:

             NAME    ADDRESS 1        ADDRESS 2
1         SMALL H
2          ZITT M
3         SMITH E    SOME ADDRESS 5   SOME ADDRESS 3
4       GLANZEL W
5        HUANG MH
6         THIJS B

1 Ответ

1 голос
/ 10 марта 2020

Вот решение tidyverse. Сначала я очищаю вторую таблицу, разбивая записи на отдельные имена. Мы можем использовать left_join для сопоставления записей:

library(tidyverse)
df2_clean <- df2 %>% 
  mutate(name = str_split(name, ";")) %>% 
  unnest(name)

df1 %>% 
  left_join(df2_clean, by = c("NAME" = "name"))
#>        NAME        address
#> 1   SMALL H           <NA>
#> 2    ZITT M           <NA>
#> 3   SMITH E SOME ADDRESS 3
#> 4   SMITH E SOME ADDRESS 5
#> 5 GLANZEL W           <NA>
#> 6  HUANG MH           <NA>
#> 7   THIJS B           <NA>

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

df1 %>% 
  left_join(df2_clean, by = c("NAME" = "name")) %>%
  group_by(NAME) %>% 
  mutate(add_c = row_number()) %>% 
  pivot_wider(id_cols = NAME, names_from = add_c, names_prefix = "address_", values_from = address)
#> # A tibble: 6 x 3
#> # Groups:   NAME [6]
#>   NAME      address_1      address_2     
#>   <chr>     <chr>          <chr>         
#> 1 SMALL H   <NA>           <NA>          
#> 2 ZITT M    <NA>           <NA>          
#> 3 SMITH E   SOME ADDRESS 3 SOME ADDRESS 5
#> 4 GLANZEL W <NA>           <NA>          
#> 5 HUANG MH  <NA>           <NA>          
#> 6 THIJS B   <NA>           <NA>

данные

df1 <- read.delim(text = "NAME
SMALL H
ZITT M
SMITH E
GLANZEL W
HUANG MH
THIJS B", stringsAsFactors = FALSE)

df2 <- read.delim(text = "name,address
SIBLEY B,SOME ADDRESS 1
STEWART C;KOCH A,SOME ADDRESS 2
HILL GM;LEE A;SMITH E,SOME ADDRESS 3
DAVIS L,SOME ADDRESS 4
MERCIER K;SMITH E;GIBBONE A,SOME ADDRESS 5
DAVIDSON S;BEKIARI A,SOME ADDRESS 6", sep = ",", stringsAsFactors = FALSE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...