r-根据字符计算两个名称之间的相似程度



有什么方法可以评估这两个名称之间的相似性吗?数据如下:

ABC  ABCD
CBD  CBD 
ABC  DEF

结果可能类似

ABC  ABCD   (3/4=) 75%
CBD  CBD    (3/3=) 100%
ABC  DEF    (0/6=) 0%

此外,字符的顺序与无关

使用intersectlength除以最小ncharmax,按行计算apply。我们可以选择处理重复

#      V1    V2
# 1   ABC  ABCD
# 2   CBD   CBD
# 3   ABC   DEF
# 4 ABCCC  ABCC
# 5 ABCCC ABCCC
# 6 ABCCC  ABCD
f <- function(x, dupes=FALSE) {
if (dupes) {
x <- sapply(x, function(x) Reduce(paste0, unique(el(strsplit(x, "")))))
}
i <- length(do.call(intersect, unname(mapply(strsplit, x, ""))))
m <- max(sapply(x, nchar))
i/m
}
apply(d, 1, f)
# [1] 0.75 1.00 0.00 0.60 0.60 0.60
apply(d, 1, f, dupes=TRUE)
# [1] 0.75 1.00 0.00 1.00 1.00 0.75

数据:

d <- structure(list(V1 = c("ABC", "CBD", "ABC", "ABCCC", "ABCCC", 
"ABCCC"), V2 = c("ABCD", "CBD", "DEF", "ABCC", "ABCCC", "ABCD"
)), class = "data.frame", row.names = c(NA, -6L))

如果我理解正确,这段代码将提供预期的输出。

fun_str_sml <- function(str1, str2){
letters_list <- c(str1, str2) %>% map(~ str_split(., "")[[1]]) %>% reduce(c)
return(letters_list %>% duplicated() %>% sum() / letters_list %>% unique() %>% length())
}
fun_str_sml("ABC", "ABCD") # => 0.75
fun_str_sml("ABC", "CDEF") # => 0.1666667 (1/6)

mapply:使用集合运算

mapply(function(x, y) length(intersect(x, y))/length(union(x, y)), 
strsplit(df$V1, ''), strsplit(df$V2, '')) * 100
#[1]  75 100   0

相关内容

  • 没有找到相关文章

最新更新