在 R 中比较字符串列表
Compare a list of strings with each other in R
我正在尝试使用包 'RecordLinkage' 中的函数 levenshteinSim() 将字符串列表相互比较。但是,我很难弄清楚如何将我的字符串列表合并到函数中,因为它只需要两个参数 str1 和 str2。我试图找到最佳方式,因为我的列表包含 4k 字符串。任何帮助深表感谢!
下面是一些示例数据:
sample <- c('apple', 'appeal', 'apparel', 'peel', 'peer', 'pear')
所以,我认为这可能就是您想要的。 RecordLinkage
包不在 CRAN 上了,所以我去找了另一个计算 Levenshtein 距离的包:
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
...
这里有一个base 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
在没有最近从 CRAN 中删除的 RecordLinkage
包的情况下,获得编辑距离或编辑相似度非常简单。
在基数 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
我正在尝试使用包 'RecordLinkage' 中的函数 levenshteinSim() 将字符串列表相互比较。但是,我很难弄清楚如何将我的字符串列表合并到函数中,因为它只需要两个参数 str1 和 str2。我试图找到最佳方式,因为我的列表包含 4k 字符串。任何帮助深表感谢!
下面是一些示例数据:
sample <- c('apple', 'appeal', 'apparel', 'peel', 'peer', 'pear')
所以,我认为这可能就是您想要的。 RecordLinkage
包不在 CRAN 上了,所以我去找了另一个计算 Levenshtein 距离的包:
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
...
这里有一个base 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
在没有最近从 CRAN 中删除的 RecordLinkage
包的情况下,获得编辑距离或编辑相似度非常简单。
在基数 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