Следующее работает нормально:
library(magrittr)
word_hash <- new.env(hash=TRUE, parent=emptyenv())
for ( word in List$Names ) {
word_hash[[ tolower(word) ]] = word
}
df$Tags <- df$Description %>%
tolower() %>%
(function(s) gsub("[^ a-z]", "", s)) %>%
strsplit(" ") %>%
sapply(function(words)
paste0(unique(unlist(sapply(words, function(key) word_hash[[key]]))), collapse=", ")
);
Использование окружения объекта используется для получения быстрой O (1) хеш-таблицы , без которой это будет очень медленно для больших словарей.
В строке gsub()
предполагается, что все ваши слова будут состоять полностью из обычных букв a-z без знаков препинания или цифр. Возможно, вам придется изменить эту строку, если некоторые слова содержат другие символы.
Аналогично, strsplit(" ")
предполагает, что все ваши слова могут быть разделены пробелом, что верно для вашего теста. Если они иногда будут разделяться на вкладки, новые строки или другие символы, вам придется немного их изменить.
Выполнение нечувствительного к регистру совпадения при одновременном отслеживании правильного регистра усложняет решение, но подразумевается в написанном вами тестовом примере. Если вас это не волнует, вы можете немного упростить.
Это решение возвращает уникальные слова в том порядке, в котором они были найдены в исходном предложении. Это похоже на то, что вы имели в виду, хотя ваш последний контрольный пример находится в другом порядке. Вы также можете подумать об обёртывании unique()
в sort()
, если хотите, чтобы теги были в согласованном порядке.