比较字符串的最佳方法

时间:2016-08-10 10:12:02

标签: r

在R中我有data喜欢这个

ID 
Peter
peter
peterr
john
johN
JOhn
...

我只是想收集所有的人,例如所有有像Peter这样名字的人都应该被收集,所以我的新数据集将是这样的

ID
Peter, peter, peterr
john, johN, JOhn
...

所以我想写一个代码peter, Peter, peterr并收集它们,我想为所有的名字做。

这样做的最佳方式是什么?

3 个答案:

答案 0 :(得分:2)

函数adist()计算字符串之间的Levenshtein distance

df1 <- data.frame(ID=c("Peter", "peter", "peterr",   "john",   "johN",   "JOhn"))
adist(df1$ID)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    0    1    2    5    5    5
[2,]    1    0    1    5    5    5
[3,]    2    1    0    6    6    6
[4,]    5    5    6    0    1    2
[5,]    5    5    6    1    0    3
[6,]    5    5    6    2    3    0

较小的距离值表示更大的相似性。向量df1$ID中六个单词“Peter”,“peter”等的索引(行)编号对应于矩阵中的列/行编号。

编程任务包括识别距离较小的对。这是一种找到差异最小的对的可能性:

dm <- adist(df1$ID)
dm <- dm*upper.tri(dm)
which(dm == 1, arr.ind=TRUE)
#     row col
#[1,]   1   2
#[2,]   2   3
#[3,]   4   5

这三对(1,2),(2,3)和(4,5)表示可以认为非常相似的字符串的索引号。那些是:“彼得”和“彼得”,“彼得”和“彼得”,以及“约翰”和“约翰”。

data.frame(apply(which(dm == 1, arr.ind=TRUE), 2, function(x) df1$ID[x]))
#    row    col
#1 Peter  peter
#2 peter peterr
#3  john   johN

可以通过使用例如which(dm > 0 & dm < 3, arr.ind=TRUE)来降低相似性阈值。这导致更多类似的对。

答案 1 :(得分:0)

你必须在该列表上的每个条目和该列表上的每个其他项目之间构建一个字符串距离矩阵......它将是巨大的。然后根据某种程度的可接受性简化该列表......例如StringDistance <2

我设计此脚本就是这样做的:https://github.com/mexindian/DataProcessing/blob/master/misspellingFixer.R 看看它是否解决了你的问题

答案 2 :(得分:-2)

两个备选建议:

来自gsub()包的

stringr。例如,如果您想在变量Peter中等同ID

gsub("pet", "Peter", data, ignore.case = TRUE)

如果你有多个等级,这个选项可能很乏味。

另一种基于@Amit Kohli提案的替代方案是另一个可能对您有用的软件包fuzzyjoin