【问题标题】:Find similar words within a variable in R在 R 中的变量中查找相似词
【发布时间】:2016-04-21 23:45:53
【问题描述】:

假设我有一个包含以下单词的变量

ChicKen120
Chicken1.20
Chicken(1.20)
Cow
cow.
cow/
cat
  1. 如何找到仅相差一两个字符的相似词?

我意识到我可以做到 grep("chicken", df$words, ignore.case=T) 查找所有与 chicken 相似的单词,但是遍历每个单词会很繁琐,即先是 chicken,然后是 cow,然后是 cat..

有没有办法在整列中找到相似的词?

  1. 我想将相似的词转换为一种标准格式,

    chicken(1.20)
    chicken(1.20)
    chicken(1.20)
    cow
    cow
    cow
    cat
    

【问题讨论】:

  • 您还没有定义“相似”是什么,而且您的问题也没有简单的答案。如果存在,您将需要一个特殊的库。
  • 使用subsub("(?i).*(chicken\\(?1\\.?20\\)?|cow).*", '\\1', x)
  • 假设“相似”是指包含所有相同字母和数字([A-z] &[0-9])的单词,忽略符号(句号、括号、斜杠)。

标签: regex r character


【解决方案1】:

考虑一个嵌套的 gsub,它会删除所有不需要的特殊字符并保留词干,甚至将所有词都移动为小写。下面删除了正反斜杠、句点和括号(如果您需要将其他模式合并到模式参数中并用管道分隔符分隔):

df$newvar <- gsub(pattern = '([[:upper:]])', perl = TRUE, 
                  replacement = '\\L\\1', gsub('[/|\\\\|\\.()]','', df$var))

由此,使用另一个gsub() 来处理其他需要的模式,您作为用户必须在了解您的需求和数据后决定这些模式。 R 很难从 120 值和 1.20 提前知道您想要 (1.20)

df$newvar <- gsub('120','(1.20)', df$newvar) 

结果

    var             newvar
1   ChicKen120      chicken(1.20)
2   Chicken1.20     chicken(1.20)
3   Chicken(1.20)   chicken(1.20)
4   Cow             cow
5   cow.            cow
6   cow/            cow
7   cat             cat
8   cat\            cat                 #<---- ADDED FOR DEMO

【讨论】:

    【解决方案2】:

    关于你的第一个问题,你可以试试adist()

    text <- c("ChicKen120","Chicken1.20","Chicken(1.20)","Cow","cow.", "cow/")
    > adist(text)
    #     [,1] [,2] [,3] [,4] [,5] [,6]
    #[1,]    0    2    4    9    9    9
    #[2,]    2    0    2   10    9   10
    #[3,]    4    2    0   12   11   12
    #[4,]    9   10   12    0    2    2
    #[5,]    9    9   11    2    0    1
    #[6,]    9   10   12    2    1    0
    

    2个或更少的矩阵元素连接最多相差2个字符的六个单词的对。

    更具体地说,可以列出不完全相同且最多相差两个字符的单词对:

    which(adist(text)<=2 & upper.tri(adist(text)), arr.ind=T)     
    #     row col
    #[1,]   1   2
    #[2,]   2   3
    #[3,]   4   5
    #[4,]   4   6
    #[5,]   5   6
    

    这里使用逻辑函数upper.tri() 仅选择矩阵的上三角形,从而防止对的双重输出(即,以相反顺序重复)并删除对角线上的相同对。

    上面列出的行号和列号对应的单词可以这样检索:

    words <- text[which(adist(text)<=2 & upper.tri(adist(text)), arr.ind=T)]
    matrix(words,ncol=2)
    #     [,1]          [,2]           
    #[1,] "ChicKen120"  "Chicken1.20"  
    #[2,] "Chicken1.20" "Chicken(1.20)"
    #[3,] "Cow"         "cow."         
    #[4,] "Cow"         "cow/"         
    #[5,] "cow."        "cow/"  
    

    【讨论】:

    • 我正试图绕着输出转。我写作时认为对象 1(ChicKen120) 和对象 3(Chicken(1.20)) 相差 4 个字符,分别是 K(.)(大写 K、两个括号和一个句号)。
    • 是的,这是正确的。这就是四个不同之处。因此矩阵元素 [1,3] 和 [3,1] 等于 4。
    • 是否可以返回相似词组。即差异小于 4 的单词。
    • 嗯.... 这在很大程度上取决于您认为的独特实例(释义 Lewis Carroll...)。但是您可以在输出矩阵中选择一列,例如matrix(words,ncol=2)[,1]。它怀疑这将接近您正在寻找的内容。
    • 我想我已经解决了这部分问题。不要运行matrix(words,ncol=2),然后运行unique(words)..我会继续工作并更新我的进度
    猜你喜欢
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    相关资源
    最近更新 更多