Encontrar subcadenas comunes entre dos variables de caracteres

Tengo dos variables de caracteres (nombres de objetos) y quiero extraer la subcadena común más grande.

a <- c('blahABCfoo', 'blahDEFfoo') b <- c('XXABC-123', 'XXDEF-123') 

Quiero lo siguiente como resultado:

 [1] "ABC" "DEF" 

Estos vectores como entrada deberían dar el mismo resultado:

 a <- c('textABCxx', 'textDEFxx') b <- c('zzABCblah', 'zzDEFblah') 

Estos ejemplos son representativos. Las cadenas contienen elementos identificadores, y el rest del texto en cada elemento vectorial es común, pero desconocido.

¿Hay una solución, en uno de los siguientes lugares (en orden de preferencia):

  1. Base R

  2. Paquetes recomendados

  3. Paquetes disponibles en CRAN

La respuesta a la supuesta duplicada no cumple estos requisitos.

Aquí hay un paquete CRAN para eso:

 library(qualV) sapply(seq_along(a), function(i) paste(LCS(strsplit(a[i], '')[[1]], strsplit(b[i], '')[[1]])$LCS, collapse = "")) 

Si no te importa usar paquetes de bioconductor, entonces, puedes usar Rlibstree . La instalación es bastante sencilla.

 source("http://bioconductor.org/biocLite.R") biocLite("Rlibstree") 

Entonces, puedes hacer:

 require(Rlibstree) ll < - list(a,b) lapply(data.frame(do.call(rbind, ll), stringsAsFactors=FALSE), function(x) getLongestCommonSubstring(x)) # $X1 # [1] "ABC" # $X2 # [1] "DEF" 

En una nota al margen: no estoy muy seguro de si Rlibstree usa libstree 0.42 o libstree 0.43 . Ambas bibliotecas están presentes en el paquete fuente. Recuerdo que me encontré con una pérdida de memoria (y por lo tanto un error) en una enorme matriz en Perl que estaba usando libstree 0.42 . Solo un aviso.

Como tengo muchas cosas que no quiero hacer, lo hice en su lugar:

 Rgames> for(jj in 1:100) { + str2< -sample(letters,100,rep=TRUE) + str1<-sample(letters,100,rep=TRUE) + longs[jj]<-length(lcstring(str1,str2)[[1]]) + } Rgames> table(longs) longs 2 3 4 59 39 2 

¿Alguien se preocupa de hacer una estimación estadística de la distribución real de las cadenas de correspondencia? ( lcstring es solo una función de fuerza bruta laminada en el hogar, el resultado contiene todas las cadenas máximas, por lo que solo miro el primer elemento de la lista)