Вот способ получить то, что вы хотите, используя пакет tm вместе с RWeka.Вам необходимо создать отдельную функцию токенизатора, которую вы подключите к функции DocumentTermMatrix
.RWeka очень хорошо играет с tm
для этого.
Если вы не хотите устанавливать RWeka из-за зависимостей java, вы можете использовать любой другой пакет, например tidytext или quanteda.Если вам нужна скорость из-за размера ваших данных, я советую использовать пакет quanteda (пример ниже кода tm).Quanteda работает параллельно, и с помощью quanteda_options
вы можете указать, сколько ядер вы хотите использовать (2 ядра по умолчанию).
note:
Обратите внимание, что надписи и биграммы в вашем словаре перекрываются.В используемом примере вы увидите, что в тексте 127 «цены» (3) и «контрактные цены» (1) будут удваивать цены.
library(tm)
library(RWeka)
data("crude")
crude <- as.VCorpus(crude)
crude <- tm_map(crude, content_transformer(tolower))
my_words <- c("contract", "prices", "contract prices", "diamond", "shamrock", "diamond shamrock")
# adjust to min = 2 and max = 3 for 2 and 3 word ngrams
RWeka_tokenizer <- function(x) {
NGramTokenizer(x, Weka_control(min = 1, max = 2))
}
dtm <- DocumentTermMatrix(crude, control=list(tokenize = RWeka_tokenizer,
dictionary = my_words))
# create data.frame from documenttermmatrix
df1 <- data.frame(docs = dtm$dimnames$Docs, as.matrix(dtm), row.names = NULL, check.names = FALSE)
Для скорости, если у вас большой корпус, может быть лучше:
library(quanteda)
corp_crude <- corpus(crude)
# adjust ngrams to 2:3 for 2 and 3 word ngrams
toks_crude <- tokens(corp_crude, ngrams = 1:2, concatenator = " ")
toks_crude <- tokens_keep(toks_crude, pattern = dictionary(list(words = my_words)), valuetype = "fixed")
dfm_crude <- dfm(toks_crude)
df1 <- convert(dfm_crude, to = "data.frame")