首页 > 解决方案 > 数据框中的部分匹配列以创建新的数据框

问题描述

我遇到了编码和部分匹配的问题。

我有两个数据帧,A 和 B。A 通过 UTF-8 编码调用,B 在 Latin1 上调用。尽管我不确定,但这可能已经是问题的一部分。这是我知道如何正确导入它的唯一方法。

编辑:我应该澄清一下。这只是样本数据。两个数据框都包含大量的行和其他列。

           A                                                        B
ID       Name    Expense                              Employee           Category
1    Mike Adall   3                                   Lothar Fiend          B2
2   Brian Adams   4                                   Rohan Sudarsh         A2
3        Adrián   1                                   Adrián Silva          A1
4     Floyd Oid   1                                   Semi Ajayi            A1
5    Semi Ajayi   4                                   Micheal Adall         A1
6      Jomu Aké   3                                   Jomü Ria Aké          B1
                                                      Brian Adams           B2
                                                      Floyd Öid Matheus     B1       

            

我一直在尝试提取 B$Employee$ 并将它们与 A$Name 部分匹配,以创建一个包含 B$Category 的新 df C。这是我想要的输出。

编辑:使用类别,我还想包括 A 和 B 的所有其他列,不包括员工。

             C
ID       Name    Expense   Category
1    Mike Adall   3        A1
2   Brian Adams   4        B2
3        Adrián   1        A1
4     Floyd Oid   1        B1
5    Semi Ajayi   4        A1
6      Jomu Aké   3        B1

到目前为止,我已经使用fuzzyjoin 包匹配了80% 的字符。

C <- A %>% fuzzy_inner_join(B, by = c(Name = "Employee"))

主要问题似乎是这些奇怪的拉丁字符,例如 Ö、ß 等,或者有时出现在“Aké”等名称的末尾。结果似乎因名称而异。

我怎样才能让它部分匹配所有的名字?

标签: rdplyrfuzzyjoin

解决方案


在基础 R 中,您可以同时使用agrepadist,如下所示:

d<-sapply(A$Name,agrep, B$Employee)
d[e]<-max.col(-adist(e<-names(Filter(Negate(length),d)), B$Employee))
cbind(A,B[unlist(d),])

 ID        Name Expense          Employee Category
5  1  Mike Adall       3     Micheal Adall       A1
7  2 Brian Adams       4       Brian Adams       B2
3  3      Adrián       1      Adrián Silva       A1
8  4   Floyd Oid       1 Floyd Öid Matheus       B1
4  5  Semi Ajayi       4        Semi Ajayi       A1
6  6    Jomu Aké       3      Jomü Ria Aké       B1

编辑:

使用stringdist包:你可以这样做:

cbind(A, B[max.col(-t(sapply(A$Name,stringdist::stringdist,B$Employee,"lcs"))),])
  ID        Name Expense          Employee Category
5  1  Mike Adall       3     Micheal Adall       A1
7  2 Brian Adams       4       Brian Adams       B2
3  3      Adrián       1      Adrián Silva       A1
8  4   Floyd Oid       1 Floyd Öid Matheus       B1
4  5  Semi Ajayi       4        Semi Ajayi       A1
6  6    Jomu Aké       3      Jomü Ria Aké       B1

推荐阅读