【问题标题】:Dealing with wrong spelling when matching text strings in R在 R 中匹配文本字符串时处理错误的拼写
【发布时间】:2013-05-26 02:30:59
【问题描述】:

我正在收集调查数据(使用开放数据工具包),而我的现场团队,祝福他们的心,有时在人名的拼写上有点创意。所以我有一个“正确”的受访者姓名,以及一些与“家庭成员姓名”变量相关的记录的年龄变量。有许多不同年龄的家庭成员。我想要受访者的年龄。

这里有一些假数据可以说明我的问题:

#the respondent
    r = data.frame(name = c("Barack Obama", "George Bush", "Hillary Clinton"))
#a male member
    m = data.frame(name = c("Barack Obama","George", "Wulliam Clenton"), age = c(55,59,70)); m$name=as.character(m$name)
#a female member
    f = data.frame(name = c("Michelle O","Laura Busch", "Hillary Rodham Clinton"), age = c(54,58,69)); f$name=as.character(f$name)
#if the responsent is the the given member, record their age.  if not, NA
    a = cbind(
        ifelse(r$name==m$name,m$age,NA)
        ,ifelse(r$name==f$name,f$age,NA)
        )
    #make a function for plyr that gives me the age of the matched respondent
    f = function(row){
        d = row[is.na(row)==0]
        ifelse(length(d)==0,NA,d)
        }
    require(plyr)
    b = aaply(a,.margins=1,.fun=f)
    data.frame(names=r$name,age=b)
                names age
    1    Barack Obama  55
    2     George Bush  NA
    3 Hillary Clinton  NA

    what.I.would.like = data.frame(names=c("Barack Obama", "George Bush", "Hillary Clinton"),age = c(55,59,70))
    1> what.I.would.like
                names age
    1    Barack Obama  55
    2     George Bush  59
    3 Hillary Clinton  70

在我的真实数据中,我有数百人和多达 13 个家庭成员。此后,我更改了调查以分别记录受访者的年龄,但我有一堆数据要清理。

【问题讨论】:

标签: r merge character spelling misspelling


【解决方案1】:

拼写问题通常使用soundex 算法的一些变体来处理。 RecordLinkage 包中有一个 R 实现。然后你需要比较的不是字符串本身,而是它们的“语音代码”:

> soundex('Clenton') == soundex('Clinton')
[1] TRUE

更新: 还有另一种方法可以确定两个词是否彼此“接近”——“距离”是词之间的某种意义。距离的一个标准度量是将第一个单词转换为第二个单词所需的单个字母替换、删除和插入的最小量。它被称为Levenshtein distance。 RecordLinkage 以及vwr 包都有相应的功能:

> levenshteinDist('Clinton', 'Clenton')
[1] 1

> vwr::levenshtein.distance('Clinton', 'Clenton')
Clenton 
  1 

然后你可以使用距离,如果距离不超过某个阈值,则考虑“接近”这个词。

更新: soundex 也可以在 phonics 包中使用。

【讨论】:

  • 两个很好的答案:我将接受声誉较低的人的答案。
  • RecordLinkage 不再适用于 R。有其他选择吗?
【解决方案2】:

我建议您使用Jaro-Winkler 距离,这是一种字符串相似度指标,旨在解决美国人口普查数据中的这一确切问题。它比 levenshtein distance 更复杂,专为处理名称而设计。您可以在 RecordLinkage 包中找到 R 实现。您需要为两个字符串的相似程度设置一个截止阈值(例如 0.8)。

install.packages('RecordLinkage','RSQLite')
require(RecordLinkage)

jarowinkler('William Clinton', "Willam Clntn")
# 0.96
jarowinkler('William Clinton', "Wuliam Clinton")
# 0.8462637
jarowinkler('William Clinton', "Hilary Clinton")
# 0.7790765

我建议为自动匹配设置一个合理的高阈值(可能是 0.9),然后将低于高阈值但高于次要低阈值(可能 0.7)的记录发送给人工审核。你应该玩这些数字,看看什么对你有用。这些值将决定您的sensitivity/specificity trade-off

【讨论】:

  • 两个很好的答案:我将接受声誉较低的人的答案。
猜你喜欢
  • 2018-05-23
  • 2021-06-06
  • 2017-04-03
  • 1970-01-01
  • 2020-08-27
  • 2011-05-15
  • 2011-05-02
  • 2021-11-21
  • 2020-07-31
相关资源
最近更新 更多