Таблица данных с двумя столбцами (3 грамма и их количеством), для которой установлен ключ в столбце ngrams. 3-граммы представляют собой односимвольный вектор из трех слов, разделенных пробелами.
set.seed(20182)
create.ngrams <- function(){
w1 <- paste(sample(letters[1:5], 3, T), collapse = '')
w2 <- paste(sample(letters[1:5], 3, T), collapse = '')
w3 <- paste(sample(letters, 5, T), collapse = '')
ngram <- paste(c(w1, w2, w3), collapse = " ")
return(ngram)
}
dt <- data.table(ngrams = replicate(100000, create.ngrams()), N = sample.int(100, 100000, replace=T))
dt[ngrams %like% '^ada cab \\.*']
Что мне нужно получить, учитывая, что 2 грамма, сколько уникальных 3 граммов появятся в таблице 3 грамма с 2 граммами в качестве основы? До сих пор подход состоит в том, чтобы фильтровать 3-граммовые таблицы и получать количество строк, используя выражения регулярных выражений и функцию data.table %like%
. К сожалению, в документации указано, что like
не использует ключ таблицы.
Примечание. В текущей реализации не используются отсортированные ключи.
Это значительно замедляет фильтрацию:
dt[ngrams %like% '^ada cab \\.*']
ngrams N
1: ada cab jsfzb 33
2: ada cab rbkqz 43
3: ada cab oyohg 10
4: ada cab dahtd 87
5: ada cab qgmfb 8
6: ada cab ylyfl 13
7: ada cab izeje 83
8: ada cab fukov 12
microbenchmark(dt[ngrams %like% '^ada cab \\.*']))
Unit: milliseconds
expr min lq mean median uq max neval
dt[ngrams %like% "^ada cab \\\\.*"] 22.4061 23.9792 25.89883 25.0981 26.88145 34.7454 100
В реальной таблице, с которой я работаю (nrow = 46856038), производительность слишком низкая для выполнения поставленной задачи:
Unit: seconds
expr min lq mean median uq max neval
t[ngrams %like% "^on the \\\\.*"] 10.48471 10.57198 11.27199 10.77015 10.94827 17.42804 100
Что я могу сделать, чтобы улучшить производительность? Я попытался немного поработать с dplyr
, но выигрыш не показался значительным.