我想在2列上应用levenshtein-s1 $ Response和s2 $ Response,稍后我需要用<0.4过滤它们并将它们绑定为Var1和Var2。 遵循代码,当我运行时,它花费了太多时间,因为要执行的记录很多(花费数小时)。请提供其他替代方法,以帮助我更快地完成该任务。
kk=cross2(.x = s2$Response, .y = s1$Response, .filter = ~levenshteinSim(.x, .y) < 0.4) %>% map(set_names, c("var1", "var2")) %>% bind_rows()
答案 0 :(得分:1)
编辑:原始答案假定在创建小标题时两个字符串向量的长度相同。
这是一种比较1000个字符串(1M组合)的两个向量的方法。您正在使用的列多长时间?如果需要更长的时间,并且假设您需要将每个元素的每个元素与另一个元素的每个元素进行比较,则需要使用不同的方法。
library(tidyverse); library(stringdist)
set.seed(42)
Response1 = stringi::stri_rand_strings(1000, 6)
Response2 = stringi::stri_rand_strings(1000, 6)
# EDIT, should work for different length vectors
combos <- expand.grid(Response1, Response2, stringsAsFactors = F) %>%
as_tibble() %>%
# Here, levenshtein distance based on the average length of the two strings
mutate(distance = stringdist(Var1, Var2, method = "lv") /
(nchar(Var1) + nchar(Var2) / 2)) %>%
filter(distance < 0.4)
答案 1 :(得分:1)
如果您的代码每次针对levenshteinSim
和s1
的每种组合都以函数调用的形式运行s2
,它将非常缓慢。也许首先列出s1
/ s2
的所有组合,然后以矢量化方式运行一次levenshteinSim
?这应该快几个数量级:
library(dplyr); library(purrr); library(RecordLinkage)
s1 <- rep(c("paul","patty","harris"), 80)
s2 <- rep(c("darren", "natty", "haris", "paulie"), 80)
system.time({
egs <- expand.grid(s1, s2, stringsAsFactors=FALSE)
lv <- do.call(levenshteinSim, unname(egs))
egs <- egs[!(lv > 0.6),]
})
# user system elapsed
# 0.11 0.00 0.1
system.time({
cross2(.x = s1, .y = s2, .filter = ~levenshteinSim(.x, .y) > 0.6)
})
# user system elapsed
# 2.98 0.00 2.97