使用具有相同字符串但顺序不同的列合并两个 data.frame

Posted

技术标签:

【中文标题】使用具有相同字符串但顺序不同的列合并两个 data.frame【英文标题】:merge two data.frame using a column with the same strings but in different order 【发布时间】:2021-07-21 16:11:27 【问题描述】:

我正在尝试使用包含字符串的列合并两个 data.frames。两列中的字符串是名称,不幸的是,它们的顺序不同。在下面的示例中,df_1 中的名称具有结构“name”+“midname”+“surname1”+“surname2”,而df_2 中的结构是“surname1”+“surname2”+“name”+“midname ”。

我首先尝试使用名称创建fuzzy merge。但是,它并没有解决问题,因为完全不同的名称之间仍然存在非零匹配。此外,定义一个可以定义一个名称何时与另一个名称完全不同的切割点并非易事。我还期望反向顺序的名称之间具有更高程度的相似性(即,(姓名+中间名)+(姓1+姓2)以不同的顺序)。

您是否有更好的方法来使用这些名称以不同的顺序合并两个 data.frame?提前致谢。

# "name"+"midname"+"surname1"+"surname2
df_1<- read.table(header = T,sep = "\t", text = "
name
Tetsurō Shoyo Hinata Kuroo
Kōtarō Tobio Kageyama Bokuto
Wakatoshi Daichi Sawamura Ushijima
Tōru  Tsukishima Oikawa
Yūji  Azumane Terushima
Kenma Kozume
")
# "surname1"+"surname2"+"name"+"midname".
df_2<- read.table(header = T,sep = "\t", text = "
name
Hinata Kuroo Tetsurō Shoyo
Kageyama Bokuto Kōtarō Tobio
Sawamura Ushijima Wakatoshi Daichi
Tsukishima Oikawa Tōru 
Azumane Terushima Yūji 
Kiyoomi Sakusa
")
library(fuzzyjoin); library(dplyr);
stringdist_join(df_1, df_2, 
                by = "name",
                mode = "inner",
                ignore_case = FALSE, 
                method = "jw", 
                max_dist = 99, 
                distance_col = "dist") %>%
  group_by(name.x) %>%
  slice_min(order_by = dist, n = 1)

结果

# A tibble: 6 x 3
# Groups:   name.x [6]
name.x                          name.y                           dist
<chr>                           <chr>                           <dbl>
1 Kenma Kozume                    "Azumane Terushima Yuji "       0.416
2 Kotaro Tobio Kageyama Bokuto    "Kageyama Bokuto Kotaro Tobio"  0.241
3 Tetsuro Shoyo Hinata Kuroo      "Kageyama Bokuto Kotaro Tobio"  0.351
4 Toru  Tsukishima Oikawa         "Tsukishima Oikawa Toru "       0.302
5 Wakatoshi Daichi Sawamura Ushi~ "Sawamura Ushijima Wakatoshi D~ 0.366
6 Yuji  Azumane Terushima         "Azumane Terushima Yuji "       0.283

【问题讨论】:

【参考方案1】:

您可以strsplit 给个人姓名、sort 他们和paste。然后使用match

x <- sapply(strsplit(df_1$name, " +"), function(x) paste(sort(x), collapse = " "))
y <- sapply(strsplit(df_2$name, " +"), function(x) paste(sort(x), collapse = " "))

cbind(df_1$name, df_2$name[match(x, y)])
#     [,1]                                 [,2]                                
#[1,] "Tetsurō Shoyo Hinata Kuroo"         "Hinata Kuroo Tetsurō Shoyo"        
#[2,] "Kōtarō Tobio Kageyama Bokuto"       "Kageyama Bokuto Kōtarō Tobio"      
#[3,] "Wakatoshi Daichi Sawamura Ushijima" "Sawamura Ushijima Wakatoshi Daichi"
#[4,] "Tōru  Tsukishima Oikawa"            "Tsukishima Oikawa Tōru "           
#[5,] "Yūji  Azumane Terushima"            "Azumane Terushima Yūji "           
#[6,] "Kenma Kozume"                       NA                                  

【讨论】:

以上是关于使用具有相同字符串但顺序不同的列合并两个 data.frame的主要内容,如果未能解决你的问题,请参考以下文章

合并具有不同列数的表

Python Pandas - 具有不同列的 Concat 数据框忽略列名

对具有相同单词但顺序不同的字符串进行分组

合并具有相同属性但 ID 不同的 NSManagedObject,与 iCloud 同步会导致重复(Core Data,Swift 1.2)

在列表中有效地重复data.table,从循环中的另一个data.table顺序替换具有相同名称的列

anagrams 查找序列里具有相同字符但顺序不同的单词