【问题标题】:Select Rows from Different Table where String from 1st table column is present in R从不同的表中选择行,其中第一个表列中的字符串存在于 R 中
【发布时间】:2021-01-26 12:32:13
【问题描述】:

如果字符串完全存在于其他表的列中,我正在尝试匹配表。但是,我设法部分加入了它,然后我应用 Levenstein 距离来获得近距离匹配。这种方法的使用和准确性有限。方法:

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

【问题讨论】:

  • 我假设 check 是 table1 而 loactions 是 table 2。是吗?
  • 是的。 check 是存在奇数字符串的表 1,LOCATIONS 是保存正确字符串的表。
  • 那么TANGA 在您的样本中作为值保存在哪里?
  • TANGA 保存在 LOCATIONS
  • 好的。这意味着 tanga 是最接近的模糊匹配,但为什么该状态被拒绝?你有匹配/距离的阈值限制吗?

标签: r string dplyr fuzzy


【解决方案1】:

您可以反转语法以避免与 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 来获得匹配的结果

【讨论】:

  • 谢谢。适用于一些调整,如 str_length() > x。较小的字符串需要过滤掉,因为它们经常出现。
【解决方案2】:

这取决于您的桌子的性质,但总的来说这是我想出的解决方案:

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 中的 2 个不同值匹配。如果您想始终从 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-03
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多