Сравните список строк друг с другом в R - PullRequest
1 голос
/ 20 февраля 2020

Я пытаюсь сравнить список строк друг с другом, используя функцию levenshteinSim () из пакета 'RecordLinkage'. Однако мне очень трудно понять, как я могу включить свой список строк в функцию, так как она принимает только два аргумента str1 и str2. Я пытаюсь найти наиболее оптимальный путь, так как мой список содержит 4k строк. Любая помощь высоко ценится!

Ниже приведены некоторые примеры данных:

sample <- c('apple', 'appeal', 'apparel', 'peel', 'peer', 'pear')

Ответы [ 3 ]

2 голосов
/ 20 февраля 2020

Итак, я думаю, что это может быть то, что вы хотите. Пакет RecordLinkage больше не находится в CRAN, поэтому я выбрал другой пакет, который вычисляет расстояние Левенштейна:

library(stringdist)

sample <- c('apple', 'appeal', 'apparel', 'peel', 'peer', 'pear')

df <- expand.grid(sample, sample) # this creates a dataframe of all combinations of the sample elements

stringdist(df$Var1, df$Var2, method = "lv")

Вывод:

[1] 0 3 3 4 4 4 3 0 3 3 4 3 3 3 0 4 5 4 4 3 4 0 1 2 4 4 5 1 0 1 4 3 4 2 1 0

И, возможно, немного более привлекательным - dplyr версия:

library(dplyr)

df %>%
    mutate(levenshtein = stringdist(Var1, Var2, method = "lv"))

, которая выводит

     Var1  Var2 levenshtein
1   apple apple           0
2  appeal apple           3
3 apparel apple           3
4    peel apple           4
5    peer apple           4
6    pear apple           4
...
1 голос
/ 20 февраля 2020

Получение расстояния Левенштейна или сходства Левенштейна довольно просто без пакета RecordLinkage, который был недавно удален из CRAN.

В базе R:

sample <- c('apple', 'appeal', 'apparel', 'peel', 'peer', 'pear')
adist(sample)
#>      [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,]    0    3    3    4    4    4
#> [2,]    3    0    3    3    4    3
#> [3,]    3    3    0    4    5    4
#> [4,]    4    3    4    0    1    2
#> [5,]    4    4    5    1    0    1
#> [6,]    4    3    4    2    1    0

Использование гораздо быстрее Пакет stringdist (который поддерживает множество альтернативных методов для расстояния Левенштейна, отметьте help("stringdist-metrics"))

stringdist::stringdistmatrix(sample, method = "lv", useNames = "strings")
#>         apple appeal apparel peel peer
#> appeal      3                         
#> apparel     3      3                  
#> peel        4      3       4          
#> peer        4      4       5    1     
#> pear        4      3       4    2    1

Если вы хотите использовать строку аналогичным образом, вы можете использовать stringsim() или stringsimmatrix, чтобы получить все Сравнение сразу (доступно только в версии для разработки; devtools::install_github("markvanderloo/stringdist/pkg")):

stringdist::stringsimmatrix(sample, method = "lv", useNames = "strings")
#>             apple    appeal apparel      peel      peer      pear
#> apple   1.0000000 0.4000000     0.4 0.2000000 0.2000000 0.2000000
#> appeal  0.5000000 1.0000000     0.5 0.5000000 0.3333333 0.5000000
#> apparel 0.5714286 0.5714286     1.0 0.4285714 0.2857143 0.4285714
#> peel    0.0000000 0.2500000     0.0 1.0000000 0.7500000 0.5000000
#> peer    0.0000000 0.0000000     0.0 0.7500000 1.0000000 0.7500000
#> pear    0.0000000 0.2500000     0.0 0.5000000 0.7500000 1.0000000

Если вы хотите перевести это в аккуратный формат, вы можете сделать следующее:

library(tidyverse)
stringdist::stringsimmatrix(sample, method = "lv", useNames = "strings") %>% 
  as.matrix() %>%
  as_tibble(rownames = "word1") %>% 
  pivot_longer(-word1, names_to = "word2", values_to = "distance")
#> # A tibble: 36 x 3
#>    word1  word2   distance
#>    <chr>  <chr>      <dbl>
#>  1 apple  apple      1    
#>  2 apple  appeal     0.4  
#>  3 apple  apparel    0.4  
#>  4 apple  peel       0.200
#>  5 apple  peer       0.200
#>  6 apple  pear       0.200
#>  7 appeal apple      0.5  
#>  8 appeal appeal     1    
#>  9 appeal apparel    0.5  
#> 10 appeal peel       0.5  
#> # ... with 26 more rows
1 голос
/ 20 февраля 2020

Вот базовое решение R для получения матрицы расстояний

z <- Map(utf8ToInt,sample)
dmat <- outer(z,z,FUN = Vectorize(function(x,y) sum(bitwXor(x,y)>0)))

такой, что

> dmat
        apple appeal apparel peel peer pear
apple       0      3       4    4    5    5
appeal      3      0       4    6    6    6
apparel     4      4       0    6    6    6
peel        4      6       6    0    1    2
peer        5      6       6    1    0    1
pear        5      6       6    2    1    0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...