【问题标题】:how can I group based on similarity in strings如何根据字符串中的相似性进行分组
【发布时间】:2017-12-02 15:50:20
【问题描述】:

我有这样的数据

df <-structure(list(label = structure(c(5L, 6L, 7L, 8L, 3L, 1L, 2L, 
    9L, 10L, 4L), .Label = c(" holand", " holandindia", " Holandnorway", 
    " USAargentinabrazil", "Afghanestan ", "Afghanestankabol", "Afghanestankabolindia", 
    "indiaAfghanestan ", "USA", "USAargentina "), class = "factor"), 
        value = structure(c(5L, 4L, 1L, 9L, 7L, 10L, 6L, 3L, 2L, 
        8L), .Label = c("1941029507", "2367321518", "2849255881", 
        "2913128511", "2927576083", "4550996370", "457707181.9", 
        "637943892.6", "796495286.2", "89291651.19"), class = "factor")), .Names = c("label", 
    "value"), class = "data.frame", row.names = c(NA, -10L))

我想获得最大的名字(以字母表示),然后查看有多少个较小和相似的名字并将它们分配到一个组中

然后再找一个下一个大名字并将它们分配到另一个组

直到没有人离开

首先我计算每个的长度,所以我会得到它们的长度

library(dplyr)
dft <- data.frame(names=df$label,chr=apply(df,2,nchar)[,1])
colnames(dft)[1] <- "label"
df2 <- inner_join(df, dft)

现在我可以简单地找到最长的字符串

df2[which.max(df2$chr),]

现在我应该看看还有哪些其他字符串的字母与这个长字符串相似。我们有这些可能性

阿富汗斯坦卡波林迪亚

可以

A
Af
Afg
Afgh
Afgha
Afghan
Afghane
.
.
.

所有可能的组合,但字母顺序应该相同(从左到右),例如应该是Afgh,不能是fAhg

所以我们只有另外两个与这个类似的字符串

Afghanestan
Afghanestankabol

这是因为它们应该完全相似,甚至不能将不同的字母(超过最大的字符串)分配给同一组

对此的期望输出如下:

label                     value     group
Afghanestan              2927576083     1
Afghanestankabol         2913128511     1
Afghanestankabolindia    1941029507     1
indiaAfghanestan        796495286.2     2
 Holandnorway           457707181.9     3
 holand                 89291651.19     3
 holandindia            4550996370      3
USA                     2849255881      4
USAargentina            2367321518      4
USAargentinabrazil      637943892.6     4

为什么印度阿富汗是一个独立的群体?因为它不完全属于另一个名称(它有部分名称来自一个或另一个)。它应该是一个更大的名字的一部分

我尝试使用这个Find similar strings and reconcile them within one dataframe,但对我没有任何帮助

我发现了其他可能有帮助的东西

require("Biostrings")
pairwiseAlignment(df2$label[3], df2$label[1], gapOpening=0, gapExtension=4,type="overlap")

但我仍然不知道如何将它们分配到一个组中

【问题讨论】:

    标签: r


    【解决方案1】:

    你可以试试

    library(magrittr)
    df$label %>% 
      tolower %>% 
      trimws %>% 
      stringdist::stringdistmatrix(method = "jw", p = 0.1) %>% 
      as.dist %>% 
      `attr<-`("Labels", df$label) %>% 
      hclust %T>% 
      plot %T>% 
      rect.hclust(h = 0.3) %>% 
      cutree(h = 0.3) %>% 
      print -> df$group
    

    df
    # label       value group
    # 1           Afghanestan   2927576083     1
    # 2       Afghanestankabol  2913128511     1
    # 3  Afghanestankabolindia  1941029507     1
    # 4      indiaAfghanestan  796495286.2     2
    # 5           Holandnorway 457707181.9     3
    # 6                 holand 89291651.19     3
    # 7            holandindia  4550996370     3
    # 8                    USA  2849255881     4
    # 9          USAargentina   2367321518     4
    # 10    USAargentinabrazil 637943892.6     4
    

    请参阅?stringdist::'stringdist-metrics',了解 stringdist 提供的字符串差异度量的概述。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-15
      • 2012-01-27
      • 1970-01-01
      • 1970-01-01
      • 2015-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多