es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Extraer cadenas basadas en múltiples patrones

Tengo miles de secuencias de ADN que se ven así :).

ref <- c("CCTACGGTTATGTACGATTAAAGAAGATCGTCAGTC", "CCTACGCGTTGATATTTTGCATGCTTACTCCCAGTC",
         "CCTCGCGTTGATATTTTGCATGCTTACTCCCAGTC")

Necesito extraer cada secuencia entre “CTACG” y “CAGTC”. Sin embargo, muchas veces estas secuencias vienen con un error (deleción, inserción, sustitución). ¿Existe alguna forma de tener en cuenta las discrepancias basándose en la distancia de Levenshtein?

ref <- c("CCTACGGTTATGTACGATTAAAGAAGATCGTCAGTC", "CCTACGCGTTGATATTTTGCATGCTTACTCCCAGTC",
         "CCTCGCGTTGATATTTTGCATGCTTACTCCCAGTC")

qdapRegex::ex_between(ref, "CTACG", "CAGTC")

> [[1]]

> [1] “GTTATGTACGATTAAAGAAGATCGT”

>

> [[2]]

> [1] “CGTTGATATTTTGCATGCTTACTCC”

>

> [[3]]

> [1] NA

reprex()

> Error in reprex(): could not find function “reprex”

“`

Creado el 2021-12-18 por el paquete reprex (v2.0.1)

De esta manera podría extraer la secuencia incluso en el último caso.

ACTUALIZACIÓN: ¿Puedo crear un diccionario con una cierta distancia de Levenshtein y luego compararlo con cada secuencia?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, se puede crear un diccionario utilizando la función stringdist::stringdistmatrix para calcular la distancia de Levenshtein entre todas las subcadenas posibles en el diccionario y las secuencias objetivo. Luego, se pueden extraer la(s) subcadena(s) más cercana(s) en base a un umbral de distancia deseado utilizando la función which.min en la matriz de distancias. Aquí tienes un ejemplo de código:

    library(stringdist)
    
    ref <- c("CCTACGGTTATGTACGATTAAAGAAGATCGTCAGTC",
             "CCTACGCGTTGATATTTTGCATGCTTACTCCCAGTC", 
             "CCTCGCGTTGATATTTTGCATGCTTACTCCCAGTC")
    
    dict <- c("CTACG", "CAGTC")
    
    # obtener todas las subcadenas posibles del diccionario
    subcadenas <- unlist(lapply(seq_along(dict), function(i){
      n <- nchar(dict[i])
      substr(dict[i], start=1:(n-3), stop=4:n)
    }))
    
    # crear la matriz de distancias entre las secuencias objetivo y las subcadenas del diccionario
    matriz_dist <- stringdistmatrix(ref, subcadenas, method="lv")
    
    # establecer la distancia umbral
    umbral <- 2
    
    # extraer la(s) subcadena(s) más cercana(s) para cada secuencia objetivo
    matches <- sapply(seq_along(ref), function(i){
      mas_cercana <- which.min(matriz_dist[i,])
      if(matriz_dist[i, mas_cercana] <= umbral){
        subcadenas[mas_cercana]
      } else {
        NA
      }
    })
    
    matches
    #> [1] "CTACG" "CTACG" NA
    

    En este ejemplo, el código crea un diccionario con las secuencias “CTACG” y “CAGTC”. Luego genera todas las subcadenas posibles de longitud 5 a partir del diccionario (“CTACG” y “AGTC” tienen solo una subcadena posible). La matriz de distancias se calcula entre las secuencias objetivo y estas subcadenas utilizando la distancia de Levenshtein. Al final, el código extrae la(s) subcadena(s) más cercana(s) para cada secuencia objetivo en base a un umbral de distancia de 2 (lo que significa que las subcadenas con una distancia de 2 o menos se consideran coincidencias). La salida muestra que las coincidencias para las dos primeras secuencias objetivo son “CTACG” (la subcadena exacta del diccionario), mientras que la última secuencia objetivo no tiene ninguna coincidencia (la subcadena más cercana tiene una distancia de 3, que es mayor que el umbral).

Comments are closed.