是否有包含Levenshtein距离计数功能的包,它是作为C或Fortran代码实现的?我有很多的字符串进行比较,并stringMatch从MiscPsycho对这个太慢了.
使用函数stringdist,我可以计算字符串之间的Levenshtein距离:它计算将字符串转换为另一个字符串所需的删除,插入和替换的次数。例如,stringdist("abc abc","abcd abc") = 1因为在第二个字符串中插入了“ d”。
是否有可能知道为获取两个琴弦之间的Levenshtein距离而进行的操作?还是要知道两个字符串之间不同的字符(在此示例中,只有“ d”)?谢谢。
library(stringdist)
stringdist("abc abc","abcde acc") = 3
Run Code Online (Sandbox Code Playgroud)
我想知道:
插入了“ d”
插入了“ e”
“ b”被替换为“ c”
或更简单地说,我想要列表(“ d”,“ e”,“ c”)。
我发现了优秀的包"stringdist",现在想用它来计算字符串距离.特别是我有一组单词,我想打印近似匹配,其中"近匹配"是通过一些算法,如Levenshtein距离.
我在shell脚本中的工作代码非常慢,我能够在stringdist中加载并生成带有指标的矩阵.现在我想将该矩阵归结为只有近似匹配的较小矩阵,例如,度量值非零但小于某个阈值.
kp <- c('leaflet','leafletr','lego','levenshtein-distance','logo')
kpm <- stringdistmatrix(kp,useNames="strings",method="lv")
> kpm
leaflet leafletr lego levenshtein-distance
leafletr 1
lego 5 6
levenshtein-distance 16 16 18
logo 6 7 1 19
m = as.matrix(kpm)
close = apply(m, 1, function(x) x>0 & x<5)
> close
leaflet leafletr lego levenshtein-distance logo
leaflet FALSE TRUE FALSE FALSE FALSE
leafletr TRUE FALSE FALSE FALSE FALSE
lego FALSE FALSE FALSE FALSE TRUE
levenshtein-distance FALSE FALSE FALSE FALSE FALSE
logo FALSE FALSE TRUE FALSE FALSE
Run Code Online (Sandbox Code Playgroud)
好的,现在我有一个(大)dist,如何将它减少回一个输出类似的列表
leafletr,leaflet,1
logo,lego,1
Run Code Online (Sandbox Code Playgroud)
仅适用于度量标准为非零且小于n …
我有一个 400,000 行的文件,其中包含需要进行地理编码的手动输入地址。文件中的相同地址有很多不同的变体,因此多次对同一地址使用 API 调用似乎很浪费。
为了减少这种情况,我想减少这五行:
Address
1 Main Street, Country A, World
1 Main St, Country A, World
1 Maine St, Country A, World
2 Side Street, Country A, World
2 Side St. Country A, World
Run Code Online (Sandbox Code Playgroud)
下降到两个:
Address
1 Main Street, Country A, World
2 Side Street, Country A, World
Run Code Online (Sandbox Code Playgroud)
使用该stringdist包,您可以将字符串的“单词”部分组合在一起,但字符串匹配算法不区分数字。这意味着它将同一街道上的两个不同房屋号码归为同一地址。
为了解决这个问题,我想出了两种方法:首先,尝试使用正则表达式将数字和地址手动分离到单独的列中,然后重新加入它们。这样做的问题是,有这么多手动输入的地址,似乎有数百种不同的边缘情况,而且它变得笨拙。
使用这个关于分组的答案和这个将单词转换为数字的答案,我有第二种方法来处理边缘情况,但在计算上非常昂贵。有没有更好的第三种方法来做到这一点?
library(gsubfn)
library(english)
library(qdap)
library(stringdist)
library(tidyverse)
similarGroups <- function(x, thresh = 0.8, method = "lv"){
grp <- integer(length(x))
Address …Run Code Online (Sandbox Code Playgroud) 受到statar包中的实验fuzzy_join函数的启发,我自己编写了一个函数,它结合了精确和模糊(通过字符串距离)匹配.我必须做的合并工作非常大(导致多个字符串距离矩阵,小于10亿个单元格),我的印象是函数编写效率不高(关于内存使用情况)和并行化以奇怪的方式实现(字符串距离矩阵的计算,如果存在多个模糊变量,而不是字符串距离本身的计算并行化).至于功能,想法是在可能的情况下匹配精确变量(以保持矩阵更小),然后在这个精确匹配的组内进行模糊匹配.我实际上认为这个功能是不言自明的.我在这里发布它是因为我希望得到一些反馈来改进它,因为我想我并不是唯一一个尝试在R中做类似事情的人(虽然我承认Python,SQL和类似的东西可能在这种情况下要更有效率.但是必须坚持一个人感觉最舒服的事情,并且使用相同的语言进行数据清理和准备在再现性方面是很好的) fuzzy_joinfuzzy_join
merge.fuzzy = function(a,b,.exact,.fuzzy,.weights,.method,.ncores) {
require(stringdist)
require(matrixStats)
require(parallel)
if (length(.fuzzy)!=length(.weights)) {
stop(paste0("fuzzy and weigths must have the same length"))
}
if (!any(class(a)=="data.table")) {
stop(paste0("'a' must be of class data.table"))
}
if (!any(class(b)=="data.table")) {
stop(paste0("'b' must be of class data.table"))
}
#convert everything to lower
a[,c(.fuzzy):=lapply(.SD,tolower),.SDcols=.fuzzy]
b[,c(.fuzzy):=lapply(.SD,tolower),.SDcols=.fuzzy]
a[,c(.exact):=lapply(.SD,tolower),.SDcols=.exact]
b[,c(.exact):=lapply(.SD,tolower),.SDcols=.exact]
#create ids
a[,"id.a":=as.numeric(.I),by=c(.exact,.fuzzy)]
b[,"id.b":=as.numeric(.I),by=c(.exact,.fuzzy)]
c <- unique(rbind(a[,.exact,with=FALSE],b[,.exact,with=FALSE]))
c[,"exa.id":=.GRP,by=.exact]
a <- merge(a,c,by=.exact,all=FALSE)
b <- merge(b,c,by=.exact,all=FALSE)
##############
stringdi <- function(a,b,.weights,.by,.method,.ncores) {
sdm <- list()
if (is.null(.weights)) {.weights <- …Run Code Online (Sandbox Code Playgroud) parallel-processing r fuzzy-comparison data.table stringdist
我想计算数据库中的 Jaro-Winkler 字符串距离。如果我将数据带入 R(使用collect),我可以轻松使用包stringdist中的函数stringdist。
但我的数据非常大,我想在将数据拉入 R之前先过滤 Jaro-Winkler 距离。
有 Jaro-Winkler 的 SQL 代码(https://androidaddicted.wordpress.com/2010/06/01/jaro-winkler-sql-code/和T-SQL的版本),但我想我不知道如何最好让 SQL 代码与dbplyr. 我很高兴尝试将该stringdist函数映射到 Jaro-Winklersql代码,但我不知道从哪里开始。但即使是更简单的事情,比如直接从 R 对远程数据执行 SQL 代码也会很棒。
我曾希望文档中的SQL 翻译dbplyr可能有所帮助,但我不这么认为。
我有一个 130 万行的出版物数据集,对于每条记录,我想从第二个包含 860 万行的数据集中检索 paper_id。这个想法是使用两个表中的多个列来查找 dataset2 中 dataset1 的匹配项,如这个功能性但简化的脚本所示:
library(fuzzyjoin); library(tidyverse)
dataset1 %>%
stringdist_left_join(dataset2 %>% select(Title, Year, Publication_id, Paper_id),
by = list(x = c("Title", "Year", "Publication_id"),
y = c("Title", "Year", "Publication_id"))
max_dist = 3, ignore_case = TRUE, distance_col = NULL)
Run Code Online (Sandbox Code Playgroud)
我这里有两个问题。首先,只有“标题”具有需要模糊匹配的变体(拼写错误、缩写、特殊字符等),但代码接受所有三个使用字段中的变体。这增加了可能与错误匹配的数量,因为类似的标题出现在不同的年份和出版物中。
我认为可以解决第一个问题的解决方案是:
library(fuzzyjoin); library(tidyverse)
dataset1 %>%
stringdist_left_join(dataset2 %>%
select(Title2 = Title, Year2 = Year, Pub_id2 = Publication_id, Paper_id),
by = list(x = c("Title", "Year", "Publication_id"),
y = c("Title2", "Year2", "Pub_id2"))
max_dist = 3, ignore_case = TRUE, distance_col = NULL) …Run Code Online (Sandbox Code Playgroud) 我有一个关于数据集中两个字符串的子字符串之间非常快速有效的比较的问题,尽管机器非常强大,但它的运行速度不够快。我有data.table2 列和大约 15 亿行,其结构如下:
library(data.table)
library(stringr)
library(stringi)
library(stringdist)
dt <- data.frame(c("002134", "024345", "176234"), c("002003", "024234", "002004"))
colnames(dt) <- c("class1", "class2")
setDT(dt)
Run Code Online (Sandbox Code Playgroud)
我想要的是一个函数,它 (1) 从两个向量的每个字符串中逐行提取前 3 位数字,(2) 比较两个向量之间的子字符串,(3) 创建一个新的布尔变量来报告两个子字符串是否相同是否相等。
所以想要的结果如下:
dt$sameclass <- c(TRUE, TRUE, FALSE)
print(dt)
class1 class2 sameclass
1: 002134 002003 TRUE
2: 024345 024234 TRUE
3: 176234 002004 FALSE
Run Code Online (Sandbox Code Playgroud)
我已经尝试过stringr和的版本,stringi无论是在data.table功能内还是在功能外。为了比较我使用的子字符串stringdist,因为据我了解可以并行化,这对我的服务器非常有益。然而,瓶颈似乎仍然是子串提取。
#stringi + stringdist without data.table:
dt$redclass1 <- stri_sub(dt$class1, to = 3)
dt$redclass2 <- stri_sub(dt$class2, to = 3)
dt[, classdist …Run Code Online (Sandbox Code Playgroud) 我想在stringdist函数中使用Jaccard相似度来确定单词袋的相似度。据我所知,使用Jaccard仅可匹配字符串中的字母。
c <- c('cat', 'dog', 'person')
d <- c('cat', 'dog', 'ufo')
stringdist(c, d, method='jaccard', q=2)
[1] 0 0 1
Run Code Online (Sandbox Code Playgroud)
因此,我们在这里看到它计算了“ cat”和“ cat”,“ dog”和“ dog”以及“ person”和“ ufo”的相似性。
我还尝试将单词转换为1个长文本字符串。以下方法满足了我的需要,但仍在计算1-(共享2克数/唯一2克总数):
f <- 'cat dog person'
g <- 'cat dog ufo'
stringdist(f, g, method='jaccard', q=2)
[1] 0.5625
Run Code Online (Sandbox Code Playgroud)
如何通过单词计算相似度?
我是 R 的真正初学者,我只有这两个列表,其中包含城市名称。一个列表包含用户生成的名称(人们拼写混乱),另一个列表包含名称的正字法。
我尝试使用包stringdist,最终得到了一个循环 (for) 并给出最接近匹配的代码。但我只能输入向量,而且我确实需要使用数据框。
这是我的代码(天哪,感觉很尴尬):
input <- "BAC" #misspelled
correct <- c("ABC", "DEF", "GHI", "JKL") #list with all correct names
shortest <- -1a
for (word in correct) {
dist <- stringdist(input, word)
#checks if it's a match!
if (dist == 0){
closest <- palavra
shortest <- 0
break
}
if(dist <= shortest || shortest < 0){
closest <- word
shortest <- dist
}
}
if(shortest == 0){
print("It's a match!")
} else {
print(closest)
}
Run Code Online (Sandbox Code Playgroud)
想法是使用这段代码来产生一个想法,我想从这里开始在数据帧的每一行中使用 …
给定的函数在R中使用"stringdist"包,并告诉将一个字符串更改为另一个字符串所需的最小更改.我想知道"%"格式中一个字符串与另一个字符串的相似程度.请帮帮我,谢谢.
stringdist("abc","abcd", method = "lv")
Run Code Online (Sandbox Code Playgroud) 对于熟悉"stringdist"软件包的人来说,这是一个问题.
我正在尝试编写一个执行以下操作的函数:
搜索很长的字符列表,例如显示的字符数量只有16个:
> stripList
[1] "AAAAAAAAAAAAAAAAAAAAAAAAAAAADAABAAADCDDAD" "BAAAABBBDACDBABAAADDCBDADBCCBDCDDCDBCDDBA"
[3] "BDDABDCCAAABABBAACADCBDADBCCBDCDDCDBCDDBA" "AADBBACDDDBABDCABAADBCADCBDDDCCC"
[5] "BBCDBBDCCBABDBCABDBBDBDDDADCDDADDDCDDCDDD" "BDDCDACABDCCBACBADCDCBDADBCCBDCDDCDDCDDBA"
[7] "BCDBADCBBDDBBBBDCBDADBCCBDCDDCDBCDDDDAAAA" "DABDDCDACABDCCBACBADC"
[9] "CABABDDCCCCACDCCDCCDADCAAAAAAAAACADADDADA" "BAABCBBBDBCDCDDADDDDCDDADBCCBDCDD"
[11] "BBDDDACDCABDDDBBACDCBDADBCCDDCDDCDDCDDBDD" "BDDABDCCAAABABBBACADCBDADBCCBDCDDCDBCDDBA"
[13] "BDDBBBBDDBDABBACDBDCBDADBCCBDCDD" "BDDABDCCAAABABBBACADCBDADBCCBDCDDCDBCDDBA"
[15] "DABDDCDACABDCCBACBADC" "BBADBACDDBABAACABCABCDCBDADBCCBDCDDCDDDDD"
Run Code Online (Sandbox Code Playgroud)
对于像这样构造的查询序列列表的每个序列的实例.
例如:
SeqName1 # queryNames
BBCDBBDCCBABDBCA # querySeqs
SeqName2 # queryNames
BBBDCCDCCCCDDDCAAACD # querySeqs
Run Code Online (Sandbox Code Playgroud)
我想查看查询序列在我的任何'stripList'中出现多少次(如果有的话)并允许1次插入,1次删除,1次替换和1次转置,并获得如下输出:
>dt
queryNames TimesFound
SeqName1 5
seqName2 145
Run Code Online (Sandbox Code Playgroud)
为此,我使用'stringdist'包的'amatch'功能,方法如下:
dt<-rapply(as.list(querySeqs), function(x) amatch(x, stripList, method = "osa", useBytes = TRUE, weight = c(d = 0.5, i = 0.5, s = 0.9, t = 0.9), maxDist=0.9))
dt<-data.frame(dt)
colnames(dt) <- …Run Code Online (Sandbox Code Playgroud) 我想根据名称选择的相似程度创建一个组变量。我已经开始使用 stringdist 包来生成距离的度量。但我不确定如何使用该输出信息来生成一组变量。我看过 hclust 但似乎使用聚类函数你需要知道你最终需要多少组,我不知道。我开始的代码如下:
name_list <- c("Mary", "Mery", "Mary", "Joe", "Jo", "Joey", "Bob", "Beb", "Paul")
name_dist <- stringdistmatrix(name_list)
name_dist
name_dist2 <- stringdistmatrix(name_list, method="soundex")
name_dist2
Run Code Online (Sandbox Code Playgroud)
我想看到一个包含两列的数据框,看起来像
name = c("Mary", "Mery", "Mary", "Joe", "Jo", "Joey", "Bob", "Beb", "Paul")
name_group = c(1, 1, 1, 2, 2, 2, 3, 3, 4)
Run Code Online (Sandbox Code Playgroud)
显然,根据我使用的距离测量方式,这些组可能略有不同(我在上面建议了两个),但我可能会选择一个或另一个来跑步。
基本上,如何在不知道我想要的集群数量的情况下从距离矩阵到组变量?