我有一个人名向量列表,其中每个向量只有名字和姓氏,我还有另一个向量列表,其中每个向量都有名字、中间名和姓氏。我需要匹配两个列表以查找包含在两个列表中的人员。因为名称不按顺序排列(某些向量将名字作为第一个值,而其他向量将姓氏作为第一个值),我想通过查找第二个列表中的哪个向量(全名)来匹配两个向量) 包含第一个列表中向量的所有值(仅名字和姓氏)。
到目前为止我做了什么:
#reproducible example
first_last_names_list <- list(c("boy", "boy"),
c("bob", "orengo"),
c("kalonzo", "musyoka"),
c("anami", "lisamula"))
full_names_list <- list(c("boy", "juma", "boy"),
c("stephen", "kalonzo", "musyoka"),
c("james", "bob", "orengo"),
c("lisamula", "silverse", "anami"))
首先,我尝试创建一个函数来检查一个向量是否包含在另一个向量中(很大程度上基于 here 中的代码)。
my_contain <- function(values,x){
tx <- table(x)
tv <- table(values)
z <- tv[names(tx)] - tx
if(all(z >= 0 & !is.na(z))){
paste(x, collapse = " ")
}
}
#value would be the longer vector (from full_name_list)
#and x would be the shorter vector(from first_last_name_list)
然后,我尝试将此函数放入 sapply() 中,以便我可以使用列表,这就是我陷入困境的地方。我可以用它来查看一个向量是否包含在向量列表中,但我不确定如何检查一个列表中的所有向量并查看它是否包含在第二个列表中的任何向量中。
#testing with the first vector from first_last_names_list.
#Need to make it run through all the vectors from first_last_names_list.
sapply(1:length(full_names_list),
function(i) any(my_contain(full_names_list[[i]],
first_last_names_list[[1]]) ==
paste(first_last_names_list[[1]], collapse = " ")))
#[1] TRUE FALSE FALSE FALSE
最后 - 虽然问一个问题可能有点太多 - 如果有人能给我任何关于如何合并 agrep() 进行模糊匹配以解决名称中的拼写错误的指示,那就太好了!如果没有,那也没关系,因为我想至少首先得到正确的匹配部分。
请您参考如下方法:
由于您正在处理列表,因此最好将它们折叠成向量,以便于处理正则表达式。但你只需按升序排列它们即可。在这种情况下,您可以轻松匹配它们:
lst=sapply(first_last_names_list,function(x)paste0(sort(x),collapse=" "))
lst1=gsub("\\s|$",".*",lst)
lst2=sapply(full_names_list,function(x)paste(sort(x),collapse=" "))
(lst3 = Vectorize(grep)(lst1,list(lst2),value=T,ignore.case=T))
boy.*boy.* bob.*orengo.* kalonzo.*musyoka.* anami.*lisamula.*
"boy boy juma" "bob james orengo" "kalonzo musyoka stephen" "anami lisamula silverse"
现在,如果您想链接 first_name_last_name_list 和 full_name_list,则:
setNames(full_names_list[ match(lst3,lst2)],sapply(first_last_names_list[grep(paste0(names(lst3),collapse = "|"),lst1)],paste,collapse=" "))
$`boy boy`
[1] "boy" "juma" "boy"
$`bob orengo`
[1] "james" "bob" "orengo"
$`kalonzo musyoka`
[1] "stephen" "kalonzo" "musyoka"
$`anami lisamula`
[1] "lisamula" "silverse" "anami"
其中名称来自first_last_list,元素来自full_name_list。处理字符向量而不是列表对您来说会很棒:
