Выберите строки из другой таблицы, где строка из 1-го столбца таблицы присутствует в R

Я пытаюсь сопоставить таблицы, если строка полностью присутствует в столбце других таблиц. Однако мне удалось частично присоединиться к нему, а затем я применяю расстояние Левенштейна, чтобы получить близкие совпадения. Этот подход имеет ограниченное применение и точность. Подход:

checkg <- check %>% 
  fuzzy_inner_join(LOCATIONS, by = c("STRING" = "STRING"), match_fun = str_detect) %>%
  rowwise() %>%
  mutate(DIST = adist(x=STRING, y=LOCATION, ignore.case = TRUE)) 

есть ли способ отобразить его следующим образом? Столбец STATUS в выходной таблице дан только для того, чтобы было ясно, что частичное совпадение строк не является целью. В выводе не требуется. Спасибо

TABLE 1

**STRING** 
BATANGAS
QINGDAO

TABLE2

**STRING**
BATNAGAS LUZON
QINGDAO PT

OUTPUT TABLE checkg

TABLE1.STRING   TABLE2.STRING    STATUS
BATANGAS        BATNAGAS LUZON   Accept
QINGDAO         QINGDAO PT       Accept
BATANGAS        TANGA            Reject

person marine8115    schedule 26.01.2021    source источник
comment
Я предполагаю, что проверка - это таблица 1, а действия - таблица 2. Так ли это?   -  person AnilGoyal    schedule 29.01.2021
comment
Да. check — это таблица 1, в которой существуют нечетные строки, LOCATIONS — это таблица, в которой сохранены правильные.   -  person marine8115    schedule 29.01.2021
comment
так где же TANGA сохраняется как значение в вашем образце?   -  person AnilGoyal    schedule 29.01.2021
comment
ТАНГА сохранена в LOCATIONS   -  person marine8115    schedule 29.01.2021
comment
В порядке. Это означает, что танга является ближайшим нечетким соответствием, но почему статус для этого отклонен? Есть ли у вас пороговое значение для совпадения/расстояния?   -  person AnilGoyal    schedule 29.01.2021
comment
Понятно! Дай мне проверить   -  person AnilGoyal    schedule 29.01.2021


Ответы (2)


Вы можете изменить синтаксис, чтобы избежать частичного совпадения из таблицы LOCATIONS.

library(fuzzyjoin)

check <- data.frame(STRING = c("BATANGAS", "QINGDAO"))
LOCATIONS <- data.frame(STRING = c("BATANGAS LUZON", "QINGDAO PT", "TANGA"))

LOCATIONS %>% 
  fuzzy_right_join(check, by = c("STRING" = "STRING"), match_fun = str_detect)

        STRING.x STRING.y
1 BATANGAS LUZON BATANGAS
2     QINGDAO PT  QINGDAO

Чтобы проверить только полные слова, вы можете сделать это.

check <- structure(list(To_check = c("BATANGAS", "QINGDAO", "ABC", "DEF"
), id = 1:4), class = "data.frame", row.names = c(NA, -4L))

check
> check
  To_check id
1 BATANGAS  1
2  QINGDAO  2
3      ABC  3
4      DEF  4

> LOCATIONS
          STRING
1 BATANGAS LUZON
2     QINGDAO PT
3          TANGA
4           ABCD

LOCATIONS %>% 
  fuzzy_right_join(check %>% mutate(dummy = paste0('\\b', To_check, '\\b')), 
                   by = c("STRING" = "dummy"), match_fun = str_detect) %>%
  select(-dummy)

          STRING To_check id
1 BATANGAS LUZON BATANGAS  1
2     QINGDAO PT  QINGDAO  2
3           <NA>      ABC  3
4           <NA>      DEF  4

излишне говорить, что вы можете использовать fuzzy_inner_join только для сопоставления результатов

person AnilGoyal    schedule 31.01.2021
comment
Спасибо. Хорошо работает с некоторыми настройками, такими как str_length() › x. Меньшие строки необходимо было отфильтровать, поскольку они часто присутствуют. - person marine8115; 31.01.2021

Это зависит от характера ваших таблиц, но в целом это решение, которое я придумал:

Table1 <- data.table(STRING = c("BATANGAS", "QINGDAO"))
Table2 <- data.table(STRING = c("BATANGAS LUZON", "QINGDAO PT", "TANGA"))

Table3 <- as.data.table(stringdist_join(Table1, Table2, by = "STRING", max_dist = 6, method = "lv", 
                                        mode = "full", distance_col = "STATUS"))

Я недостаточно знаком с dplyr, чтобы воспроизвести его там, поэтому в своем примере я использую data.table.

Этот код даст следующий результат:

STRING.x    STRING.y          STATUS
BATANGAS    BATANGAS LUZON    6
BATANGAS    TANGA             3
QINGDAO     QINGDAO PT        3
QINGDAO     TANGA             4

Теперь это становится немного сложнее. Я могу представить, что вы не хотите, чтобы TANGA совпадала с двумя разными значениями в STRING.x. Однако в этом примере вы хотите, чтобы BATANGAS совпадал с двумя разными значениями в STRING.y. Если вы хотите всегда удалять дубликаты из STRING.y, вы можете сделать это, используя это:

Table3 <- Table3[ , .SD[which.min(STATUS)], by = STRING.y]

который будет производить:

STRING.y          STRING.x    STATUS
BATANGAS LUZON    BATANGAS    6
TANGA             BATANGAS    3
QINGDAO PT        QINGDAO     3
person Wietse de Vries    schedule 28.01.2021