[英]Comparing two columns of two dataframes based on partial string match
我有兩個示例數據框, df1
和df2
,如下所示。 df1
具有選定的網球比賽裝置列表,其中包含球員姓名( player1_name
, player_name2
)和比賽日期。 全名在這里用於球員。
df2
列出了每個日期的所有網球比賽結果( winner
、 loser
)。 在這里,使用名字的第一個字母和完整的姓氏。 賽程和結果的球員姓名是從不同的網站上抓取的。 因此,在某些情況下,姓氏可能不完全匹配。 考慮到這一點,我想在df1
中添加一個新列,說明是 player1 還是 player2 獲勝。 基本上,我想通過給定相同日期的某些部分匹配方式將player1_name
和player2_name
從df1
映射到 df2 的獲勝者和失敗者。
dput(df1)
structure(list(date = structure(c(18534, 18534, 18534, 18534,
18534, 18534, 18534), class = "Date"), player1_name = c("Laslo Djere",
"Hugo Dellien", "Quentin Halys", "Steve Johnson", "Henri Laaksonen",
"Thiago Monteiro", "Andrej Martin"), player2_name = c("Kevin Anderson",
"Ricardas Berankis", "Marcos Giron", "Roberto Carballes", "Pablo Cuevas",
"Nikoloz Basilashvili", "Joao Sousa")), row.names = c(NA, -7L
), class = "data.frame")
dput(df2)
structure(list(date = structure(c(18534, 18534, 18534, 18534,
18534, 18534, 18534, 18534, 18534, 18534, 18534, 18534, 18534,
18534, 18534, 18534, 18534, 18534, 18534, 18534), class = "Date"),
winner = c("L Harris", "M Berrettini", "M Polmans", "C Garin",
"A Davidovich Fokina", "D Lajovic", "K Anderson", "R Berankis",
"M Giron", "A Rublev", "N Djokovic", "R Carballes Baena",
"A Balazs", "P Cuevas", "T Monteiro", "S Tsitsipas", "D Shapovalov",
"G Dimitrov", "R Bautista Agut", "A Martin"), loser = c("A Popyrin",
"V Pospisil", "U Humbert", "P Kohlschreiber", "H Mayot",
"G Mager", "L Djere", "H Dellien", "Q Halys", "S Querrey",
"M Ymer", "S Johnson", "Y Uchiyama", "H Laaksonen", "N Basilashvili",
"J Munar", "G Simon", "G Barrere", "R Gasquet", "J Sousa"
)), row.names = c(NA, -20L), class = "data.frame")
我創建了一個自定義函數,該函數可以使用 RecordLinkage 包將字符串與字符串向量中的最接近匹配項進行匹配。 我可能會使用這個函數編寫一個非常低效的代碼,但在去那里之前,我想看看我是否可以以更有效的方式來完成。
ClosestMatch <- function(string, stringVector,max_threshold=0.5) {
df<- character()
for (i in 1:length(string)) {
distance <- levenshteinSim(string[i], stringVector)
if (max(distance)>=max_threshold) {
df[i]<- stringVector[which.max(distance)]
}
else {
df[i]= NA
}
}
return(df)
}
我stringdist
了一下使用stringdist
:
library(stringdist)
for (i in 1:nrow(df1)) {
#this first part combines the names of player1 and player2
#and finds the closest match to the player combinations in df2
d <-
stringdist(
paste(df1$player1_name[i], df1$player2_name[i]),
paste(df2$winner, df2$loser),
method = "cosine")
#I like using the cosine method as it returns a decimal as opposed to an integer
#then, added winner and loser columns to df1 based on which row in df2 had the closest match
#(i.e. lowest stringdist)
df1$winner[i] <- df2[which(d == min(d)), 2]
df1$loser[i] <- df2[which(d == min(d)), 3]
}
#adding another loop that makes the names in the winner/loser columns
#change to their closest match in the player1 and player2 columns
for(i in 1:nrow(df1)){
n <- stringdist(df1$winner[i], c(df1$player1_name[i], df1$player2_name[i]), method = "cosine")
if (n[1] > n[2]){df1$winner[i] <- df1$player2_name[i]
df1$loser[i] <- df1$player1_name[i]}
if (n[1] < n[2]){df1$winner[i] <- df1$player1_name[i]
df1$loser[i] <- df1$player2_name[i]}
}
> df1
date player1_name player2_name winner loser
1 2020-09-29 Laslo Djere Kevin Anderson Kevin Anderson Laslo Djere
2 2020-09-29 Hugo Dellien Ricardas Berankis Ricardas Berankis Hugo Dellien
3 2020-09-29 Quentin Halys Marcos Giron Marcos Giron Quentin Halys
4 2020-09-29 Steve Johnson Roberto Carballes Roberto Carballes Steve Johnson
5 2020-09-29 Henri Laaksonen Pablo Cuevas Pablo Cuevas Henri Laaksonen
6 2020-09-29 Thiago Monteiro Nikoloz Basilashvili Thiago Monteiro Nikoloz Basilashvili
7 2020-09-29 Andrej Martin Joao Sousa Andrej Martin Joao Sousa
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.