如何在两个姓名列表中寻找匹配项?

4

我有两个包含名字的长向量(list.1list.2)。我想运行一个循环,检查 list.2 中的任何名称是否与 list.1 中的任何名称匹配。如果匹配,则将匹配名称在列表 list.1 中的位置的值添加到向量 result 中。

 for (i in list.2){
  for (j in list.1){
    if(length(grep(list.2[i], list.1[j]), ignore.case=TRUE)==0){
      append(result, j)
      break
    } else append(nameComment.corresponding, 0)
  }
}

上述代码是一种非常暴力的方法,由于我的向量长度分别为5,000和60,000,它可能需要运行超过360,000,000个周期。我该如何改进它呢?


你看过%in%或者match()吗? - A5C1D2H2I1M1N2O1R2T1
下面的建议有用吗?如果一个答案解决了你的问题,你可能想要考虑给它点赞或标记为已接受的答案,通过在合适的答案旁边打勾来显示问题已经得到了解答。你不必这样做,但这有助于保持网站没有未回答的问题,并奖励那些花时间解决你问题的人。 - Simon O'Hanlon
这完全是集合操作intersect的用法...在你的情况下,将其包装在match(intersect(list.1, list.2), list.1)中。永远不要编写O(N1*N2)循环... - smci
2个回答

4

which%in%可能非常适合这个任务,或者根据你的意图选择使用match。需要注意的是,match返回第一个匹配项在第二个参数中的索引(也就是说,如果查找表中有多个值与之匹配,则只返回第一个匹配项):

set.seed(123)
#  I am assuming these are the values you want to check if they are in the lookup 'table'
list2 <- sample( letters[1:10] , 10 , repl = T )
[1] "c" "h" "e" "i" "j" "a" "f" "i" "f" "e"

#  I am assuming this is the lookup table
list1 <- letters[1:3]
[1] "a" "b" "c"

#  Find which position in the lookup table each value is, NA if no match
match(list2 , list1 )
[1]  3 NA NA NA NA  1 NA NA NA NA

为了完整起见,还有match(y, x)(它的工作方式略有不同)和which(is.element(x, y))(其中is.element%in%相同,但对于新用户来说,函数名称可能更具描述性,因为函数名称比%in%更直观)。 - A5C1D2H2I1M1N2O1R2T1
@AnandaMahto 谢谢。实际上这个例子很糟糕(在我看来!),但当时我的小男孩一直缠着我!我会稍微修改一下的。 - Simon O'Hanlon

1

这正是集合操作 intersect/union/setdiff() 的用途所在:

list.1 = c('Alan','Bill','Ted','Alice','Carol')
list.2 = c('Carol','Ted')
intersect(list.1, list.2)
 "Ted" "Carol"

...或者如果你真的想要list.1中的索引:

match(intersect(list.1, list.2), list.1)
  3 5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接