Используя stringi
, в моем смоделированном примере он работает почти в 50 раз быстрее, чем grepl
:
# sample data
set.seed(47)
a = replicate(150000, sample(letters, size = 6))
b = replicate(600, sample(letters, size = 3))
big_pat = paste(b, collapse = "|")
ans_stringi = stri_detect_regex(a, big_pat)
ans_grepl = grepl(pattern = big_pat, x = a)
identical(ans_stringi, ans_grepl)
# [1] TRUE
# timing comparison
microbenchmark::microbenchmark(
stringi = stri_detect_regex(a, big_pat),
grepl = grepl(pattern = big_pat, x = a),
times = 10L
)
# Unit: milliseconds
# expr min lq mean median uq max neval
# stringi 344.5289 348.7399 404.7191 409.6438 443.1995 477.3867 10
# grepl 17323.6438 18743.7462 19058.1780 19192.0434 20012.5553 20061.1821 10
Альтернативой без регулярных выражений является использование fixed
шаблонов и выполнение одного grepl
за b
пункт.Но я обнаружил, что это намного медленнее, чем приведенное выше решение.
ans_fixed = apply(sapply(Item_B, grepl, x = Item_A, fixed = TRUE), MAR = 1, FUN = any)
Использование fixed = TRUE
сделает каждый grepl
очень быстрым, но их все еще много, и он создает большое (length(a)
на length(b)
) матрица для результатов, которая могла бы съесть много памяти.В моем тестировании grepl
был быстрее, чем stri_detect_fixed
здесь.
Если у вас проблемы с памятью, делайте это порциями, скажем, 100 Item_B
значений за раз.