在 R 中使用 for 循环的字符串之间的 Jaccard 相似度

Jaccard Similarity between strings using a for loop in R

我正在尝试计算大型名称向量中每对名称之间的 jaccard 相似度(请参阅下面的小示例)并将它们的 jaccard 相似度存储在矩阵中。我的函数只是返回 NULL。我做错了什么?

library(dplyr)

df = data.frame(matrix(NA, ncol=3, nrow=3))
df = df %>%
    mutate_if(is.logical, as.numeric)

names(df) = c("A.J. Doyle", "A.J. Graham", "A.J. Porter")
draft_names = names(df) 
row.names(df) = c("A.J. Feeley", "A.J. McCarron", "Aaron Brooks")
quarterback_names = row.names(df)

library(stringdist)

jaccard_similarity = function(d){
  for (i in 1:nrow(d)){
    for(j in 1:ncol(d)){
      d[i,j] = stringdist(quarterback_names[i], draft_names[j], method ='jaccard', q=2)
    }
  }
}

df = jaccard_similarity(df)

您需要return您更改后的数据框:

jaccard_similarity = function(d){
  for (i in 1:nrow(d)){
    for(j in 1:ncol(d)){
      d[i,j] = stringdist(quarterback_names[i], draft_names[j], method ='jaccard', q=2)
    }
  }
  return(d)
  // ^^^
}


之后 jaccard_similarity(df) 产生

              A.J. Doyle A.J. Graham A.J. Porter
A.J. Feeley    0.6428571   0.7500000   0.7500000
A.J. McCarron  0.7647059   0.7777778   0.7777778
Aaron Brooks   1.0000000   1.0000000   1.0000000

您在 for 循环后没有返回任何东西。在函数末尾使用 return(d)

这个问题也是outer的经典用例:

outer(quarterback_names,draft_names,FUN=stringdist,method="jaccard",q=2)
          [,1]      [,2]      [,3]
[1,] 0.6428571 0.7500000 0.7500000
[2,] 0.7647059 0.7777778 0.7777778
[3,] 1.0000000 1.0000000 1.0000000

原因: 没有明确的 return。

Reference

你可以像下面这样添加打印和调试并跟踪

jaccard_similarity = function(d){
  for (i in 1:nrow(d)){
    for(j in 1:ncol(d)){
      d[i,j] = stringdist(quarterback_names[i], draft_names[j], method ='jaccard', q=2)
      print(d[i,j])
    }
  }
  return(d)
}

输出:

[1] 0.6428571
[1] 0.75
[1] 0.75
[1] 0.7647059
[1] 0.7777778
[1] 0.7777778
[1] 1
[1] 1
[1] 1

您只需调用 jaccard_similarity(df) 即可获取值。

output  <-jaccard_similarity(df)

              A.J. Doyle A.J. Graham A.J. Porter
A.J. Feeley    0.6428571   0.7500000   0.7500000
A.J. McCarron  0.7647059   0.7777778   0.7777778
Aaron Brooks   1.0000000   1.0000000   1.0000000

并将输出分配给新变量而不是覆盖现有的 df