Ответ 1
Подход sqldf
является самым быстрым на моей машине для ваших данных примера, но здесь есть более быстрая версия data.table
, если она помогает.
library(data.table)
library(sqldf)
## Example data
v1 <- paste0(c("asdasd asdasd 768jjhknmnmnj", "78967ggh","kl00896754","kl008jku"),
1:10000)
v2 <- paste0(c("mnj", "12345","kl008","lll1"), 1:10000)
data1 <- data.table(col1=v1, key="col1")
data2 <- data.table(col2=v2, key="col2")
## sqldf version
system.time(
ans1 <- data.table(sqldf(
"select *
from data1 a inner join data2 b
on instr(a.col1, b.col2)", drv="SQLite"))
)
## user system elapsed
## 17.579 0.036 17.654
## parallelized data.table version
suppressMessages(library(foreach)); suppressMessages(library(doParallel))
cores <- detectCores() ## I've got 4...
clust <- makeForkCluster(cores)
registerDoParallel(clust)
system.time({
batches <- cores
data2[, group:=sort(rep_len(1:batches, nrow(data2)))]
ans2 <- foreach(
i=1:batches, .combine=function(...) rbindlist(list(...)),
.multicombine=TRUE, .inorder=FALSE) %dopar% {
CJ(col1=data1[, col1], col2=data2[group==i, col2])[,
alike:=col1 %like% col2, by=col2][
alike==TRUE][, alike:=NULL][]
}
})
## user system elapsed
## 0.185 0.229 30.295
stopCluster(clust)
stopImplicitCluster()
Я запускаю это на OSX - вам может потребоваться настроить код параллелизации для других операционных систем. Кроме того, если ваши фактические данные больше и у вас заканчивается память, вы можете попробовать более крупные значения batches
.