2016-08-17 7 views
0

У меня есть большой список описаний продуктов что-то вродеСтрока подобия Поиск в R

Water bottles 1L 
Water Can 1L 
Aerated Drinks 1L 
Chips Potato 
Doritos Chips 
Bread 
Yogurt 300ML 
Milk 

Ofcourse список в миллионах.

Я пытаюсь создать сходство поиска. Я хочу функцию поиска, которая будет отображать описания подобия. Если я буду искать в Milk Products, он должен принести молоко, масло, йогурт, что-то в этом роде.

Для этого я использовал levenshteinSim и запустил все описания в Loop и сравнил с моей строкой поиска. К тому времени, когда он побежал за всеми миллионами записей, это занимает много времени. Есть ли какой-либо алгоритм, который будет принимать фрейм данных и строку в качестве входного параметра и минимальный балл, чтобы получить значения?

+0

Если вы хотите использовать специально 'levenshteinSim' просто заменить' 'adist' с levenshteinSim' во втором редактировать из моего поста ниже. Если вы считаете, что предлагаемое решение не отвечает на этот вопрос, добавьте комментарий, касающийся того, что конкретно вы хотите, а не повторного редактирования вашего вопроса. – Barker

ответ

2

Это довольно прямо вперед случай для grep

grep("milk", searchDF[["description"]], ignore.case = TRUE) 

EDIT:

К сожалению, не понимаете, что вы искали список dataframes, а не только один dataframe со всеми описаниями в одном длинная строка.

vapply(searchList, function(x) any(grepl("milk", x, ignore.case = TRUE)), 
     logical(1)) 

vapply будет выглядеть через все элементы вашего списка в векторизованных моды и ускорить процесс. grepl походит на grep, но возвращает логический, а не индекс. any затем проверяет все логические элементы, возвращенные grepl, чтобы узнать, была ли строка поиска "milk". logical(1) в конце просто указывает, что функция вернет одно логическое значение для каждого индекса searchList. Вы также можете использовать sapply и не должны ставить logical(1) в конце, но vapply в целом безопаснее, так как sapply иногда возвращает неожиданный тип данных.

Edit 2:

Я не знаком с levenshteinSim но функция adist в utils также вычисляет расстояние Левенштейна. Если вы хотите минимальное расстояние, а не просто наличие или отсутствие в списке строк, вы можете использовать аналогичную стратегию, но с adist.

vapply(searchList, function(x) min(adist(x, "milk 1L", 
             ignore.case = TRUE)), 
     numeric(1)) 
+0

Это очень помогает. У меня есть другой вопрос: есть ли способ, если я дам levenshteinSim ('A', 'b'), это дает те же значения, что и levenshteinSim ('b', 'A'). Возможно ли, что сравнение только одностороннее. Что-то вроде levenshteinSim («Juice Mixer», «Pansonic Mixer for Juice») должно давать 100% -ую совпадение. Одностороннее совпадение не должно давать 100% этого сравнения levenshteinSim («Pansonic Mixer for Juice», «Juice Mixer») –

+0

Вам нужно быть более конкретным для вашего критерия подсчета очков, поскольку вы больше не вычисляете расстояние Левенштейна. Например, если 'newDistanceFunction (« кино »,« iceman »)' возвращается на 100%, поскольку все буквы в «кино» находятся в «iceman»? Если это всего лишь целые слова, как вы хотите, чтобы это касалось частичных матчей? Должна ли 'NewDistanceFunction (« Молочная машина »,« Доильная машина ») быть 100% или немного меньше? Как насчет 'newDistanceFunction (« Доильный аппарат »,« Молочная машина »)? – Barker