2015-12-26 4 views
1

Я ищу функцию (назовем ее scramblematch), которая может сделать следующее.R: указать, существует ли подстрока в другой строке

query='one five six' 
target1='one six two six three four five ' 
target2=' two five six' 

scramblematch(query, target1) возвращает TRUE и

scramblematch(query, targ2) возвращает FALSE

Пакет stringdist может быть то, что мне нужно, но я не знаю, как использовать его.

Update1

Используйте случай для функции Я ищу: У меня есть набор данных с введенными данными постепенно на протяжении многих лет. Значения для одного текстового поля (textfield) набора данных не стандартизированы, поэтому люди вступили по-разному. Теперь я хочу очистить эти данные, используя стандартизованный набор значений для textfield. Все те значения, которые описывают одни и те же вещи разными формулировками, заменяются стандартизованными значениями. Например (я делаю это):

В моем стандартизованном выборе значений (назовем это lookupfactors), у меня есть lookupfactors=c('liver disease', 'and more'). В textfield я следующие строки:

liver cancer disease 
some other thing 
male, liver fibrosis disease 
yet another thing 
failure of liver, disease 

Хочу в конечном итоге, чтобы иметь строку 1, 3 и 5 (потому что они имеют «печень» и «заболевание» в содержании) должны быть заменены от liver disease. Здесь я предполагаю, что люди, которые ввели данные, не знают точного термина, но они знают ключевые слова, чтобы выразить это. Поэтому слова в значениях lookupfactors являются подстрокой/подмножеством в textfield.

+3

Вы хотите проверить, отображается ли каждое слово в 'query' в целевой строке? Если это так, вы можете попробовать «Уменьшить» («&», lapply (strsplit (query, «») [[1]], grepl, c (target1, target2))). – nicola

+0

Очень хорошая демонстрация 'Уменьшить'. Использование «Уменьшить» - вот что мне нужно: «Уменьшить (« & », lapply (strsplit (query,« ») [[1]], grepl, target1))' и 'Уменьшить (" & ", lapply (strsplit (query, "") [[1]], grepl, target2)) '. Спасибо. Но мне интересно, есть ли другой более быстрый метод. – biocyberman

+1

Вам не нужны отдельные вызовы, если вам нужна скорость. Просто создайте вектор целевых строк и используйте мою строку. Думаю, это должно быть достаточно быстро. – nicola

ответ

3

Одним из вариантов реализации это с %in% и strsplit:

scramblematch <- function(query, target, sep = " ") { 
    all(unlist(strsplit(query, sep)) %in% unlist(strsplit(target, sep))) 
} 
scramblematch(query, target1) 
#[1] TRUE 
scramblematch(query, target2) 
#[1] FALSE 

Векторизованных подход с использованием stringi может быть

library(stringi) 
scramblematch <- function(query, target, sep = " ") { 
    q <- stri_split_fixed(query, sep)[[1L]] 
    sapply(stri_split_fixed(target, sep), function(x) { 
    all(q %in% x) 
    }) 
} 

scramblematch(query, c(target1, target2)) 
#[1] TRUE FALSE 
+3

Возможно также (аналогично) 'library (stringi); all (stri_detect_fixed (target1, stri_split_fixed (query, "") [[1]])) ' –

+0

@DavidArenburg, да, я тоже так думал. –

3

Вы можете попробовать (улучшение fixed=TRUE от @ Давида комментарий):

scramblematch<-function(query,target) { 
    Reduce("&",lapply(strsplit(query," ")[[1]],grepl,target,fixed=TRUE)) 
} 

Некоторые тест:

query='one five six' 
target1='one six two six three four five ' 
target2=' two five six' 
target<-rep(c(target1,target2),10000) 
system.time(scramblematch(query,target)) 
# user system elapsed 
#0.008 0.000 0.008 
scramblematchDD <- function(query, target, sep = " ") { 
    all(unlist(strsplit(query, sep)) %in% unlist(strsplit(target, sep))) 
} 
system.time(vapply(target,scramblematchDD,query=query,TRUE)) 
# user system elapsed 
#0.657 0.000 0.658 

vapply в растворе @docendodiscimus необходима, так как она не векторную.

+2

Возможно, добавьте 'fixed = TRUE' для некоторого дополнительного увеличения скорости. –

+1

Мой ответ не векторизован, потому что они не просили такую ​​реализацию в вопросе. Разумеется, было бы бессмысленно strsplit запрос каждый раз, если скорость является проблемой. –

+1

@DavidArenburg Tx, что ускоряет работу в 3 раза. – nicola

Смежные вопросы