2016-02-13 3 views
3

Есть ли (простая) возможность идентифицировать общий шаблон, который разделяют две строки? Вот небольшой пример, чтобы понять, что я имею в виду:Определить общий шаблон

У меня есть две переменные, содержащие строку. Оба включают один и тот же шаблон («ABC»), а также некоторый «шум».

a <- "xxxxxxxxxxxABCxxxxxxxxxxxx" 
b <- "yyyyyyyyyyyyyyyyyyyyyyyABC" 

Позволяет сказать, что я не знаю, общий шаблон, и я хочу, R, чтобы выяснить, что обе строки содержат «ABC». Как я могу это сделать?

* редактировать

Первый пример был, возможно, немного к упрощенным. Вот пример из моих реальных данных.

a <- "DUISBURG-HAMBORNS" 
b <- "DUISBURG (-31.7.29)S" 

Обе строки содержат «DUISBURG», которые я хочу, чтобы функция идентифицировала.

* редактировать

Я принял решение, предложенное в ссылке, публикуемую в комментариях. Но я все еще не совсем то, что хочу.

library(qualV) 
LCS(strsplit(a[1], '')[[1]],strsplit(b[1], '')[[1]])$LCS 

[1] "D" "U" "I" "S" "B" "U" "R" "G" "-" " " " " "S" 

Если функция ищет наибольшую общую подпоследовательность два векторов, почему она не остановится после "D" "U" "I" "S" "B" "U" "R" "G"? ,

+0

Мы должны знать больше о возможных общих паттернах и этом «шуме». Например, «abc» и «cda» дают 2 общих шаблона «a» и «c»? – Julius

+0

Хорошо, есть точка. Мне нужны шаблоны с 3 или 4 элементами. – Alex

+2

http://stackoverflow.com/questions/16196327/find-common-substrings-between-two-character-variables –

ответ

5

Функция LCS из qualV пакета (в Find common substrings between two character variables; не возможный дубликат) делает что-то другое, чем то, что вам нужно. Он решает the longest common subsequence problem, где подпоследовательности не требуется занимать последовательные позиции в исходных последовательностях.

Что у вас есть the longest common substring problem, для которых можно использовать this алгоритм, а вот код при условии, что существует единственный (с точки зрения длины) наибольшей общей подстроки:

a <- "WWDUISBURG-HAMBORNS" 
b <- "QQQQQQDUISBURG (-31.7.29)S" 

A <- strsplit(a, "")[[1]] 
B <- strsplit(b, "")[[1]] 

L <- matrix(0, length(A), length(B)) 
ones <- which(outer(A, B, "=="), arr.ind = TRUE) 
ones <- ones[order(ones[, 1]), ] 
for(i in 1:nrow(ones)) { 
    v <- ones[i, , drop = FALSE] 
    L[v] <- ifelse(any(v == 1), 1, L[v - 1] + 1) 
} 
paste0(A[(-max(L) + 1):0 + which(L == max(L), arr.ind = TRUE)[1]], collapse = "") 
# [1] "DUISBURG" 
+0

Я нашел эту функцию почти идеальным решением для аналогичной проблемы, хотя у меня есть одна проблема. Как заставить его обрабатывать случаи, когда нет подстроки commong? В частности, меня не интересует точная подстрока, но ее длина, пока я запускаю этот, а затем использую nchar, но функция возвращает ошибку, когда две строки не имеют совпадений. – PrzeM

+0

Я обнаружил, что в вышеупомянутом case 'ones' пуст, поэтому предложение if после его решения. Еще одна проблема, связанная с тем, как правильно применить ее к моему набору данных? Мне нужно сравнить строки из двух столбцов по строкам во всей таблице. – PrzeM

+0

@PrzeM, вы всегда можете запустить цикл 'for'. Кроме того, вы можете определить функцию 'fun', которая принимает вектор длины 2 в качестве аргумента (первым элементом будет' a', second 'b') и« apply (df, 1, fun) ». – Julius