library(dada2)
library(Biostrings)
dada2: Herramienta principal para el análisis de
datos de secuenciación de amplicones (ej. 16S, ITS). Permite filtrar
lecturas, corregir errores y asignar taxonomía, obteniendo variantes de
secuencia exactas (ASVs).
📖 Documentación
📑 Artículo (Nature
Methods, 2016)
Por información más detallada de cada función asociada a los paquetes utilice help(“función”) en RStudio (por ej. help(“learnErrors”))
path <- setwd()
list.files(path)
fnFs <- sort(list.files(path, pattern="_1.fastq", full.names = TRUE))
fnRs <- sort(list.files(path, pattern="_2.fastq", full.names = TRUE))
sort()
En el flujo de trabajo, la función sort()
se utiliza
para ordenar alfabéticamente los nombres de los
archivos FASTQ listados con list.files()
.
Esto asegura que las lecturas forward (_1.fastq
) y
reverse (_2.fastq
) queden organizadas de manera
correcta antes de ser procesadas, evitando desajustes entre las
muestras.
sample.names <- sapply(strsplit(basename(fnFs), "_"), `[`, 1)
sample.metadata <-read.csv("sampleData_alimentos.csv")
plotQualityProfile(fnFs[1:2])
plotQualityProfile(fnRs[1:2])
plotQualityProfile()
La función plotQualityProfile()
del paquete
dada2 permite visualizar la calidad de las
lecturas en archivos FASTQ.
En este caso, se aplica a las dos primeras muestras
(fnFs[1:2]
) para inspeccionar de forma preliminar la
distribución de calidad a lo largo de las posiciones de las
secuencias.
Este gráfico es muy útil porque:
- Muestra la caída típica de la calidad hacia el extremo derecho de las
lecturas.
- Permite decidir hasta qué posición recortar (trimming) las
secuencias.
- Ayuda a identificar problemas en la calidad de los datos de
secuenciación.
filtFs <- file.path(path, "filtered", paste0(sample.names, "_F_filt.fastq.gz"))
filtRs <- file.path(path, "filtered", paste0(sample.names, "_R_filt.fastq.gz"))
out <- filterAndTrim(fnFs, filtFs, fnRs, filtRs, truncLen=c(290,200),
maxN=0, maxEE=c(2,2), truncQ=2, rm.phix=TRUE, compress=TRUE, multithread=FALSE)
save(out, file="out")
filterAndTrim()
La función filterAndTrim()
del paquete
dada2 se utiliza para filtrar y
recortar las lecturas crudas en formato FASTQ, eliminando
secuencias de baja calidad antes del análisis.
truncLen=c(290,200): recorta las lecturas forward a 290 bases y las reverse a 200 bases.
maxN=0: descarta cualquier lectura con nucleótidos ambiguos (N).
maxEE=c(2,2): elimina lecturas con un número esperado de errores mayor a 2 (tanto en forward como en reverse).
truncQ=2: recorta la lectura en el primer punto donde la calidad baja a Q=2 o menos.
rm.phix=TRUE: elimina contaminantes derivados del control PhiX.
compress=TRUE: guarda los archivos filtrados en formato comprimido.
multithread=FALSE: ejecuta el proceso en un solo hilo (en Linux/Mac puede ponerse TRUE para usar múltiples núcleos).
Se puede utilizar trimLeft para remover secuencias de primers.
errF <- learnErrors(filtFs, multithread=FALSE)
save(errF, file="errF")
errR <- learnErrors(filtRs, multithread=FALSE)
save(errR, file="errR")
learnErrors()
La función learnErrors()
del paquete
dada2 se utiliza para aprender los perfiles de
error a partir de las lecturas filtradas.
El algoritmo de DADA2 modela explícitamente las probabilidades de error
de cada posición de la secuencia, lo cual es esencial para distinguir
entre verdaderas variantes biológicas y errores de secuenciación.
filtFs: conjunto de lecturas forward filtradas que se utilizan para estimar el modelo de errores.
multithread=FALSE: ejecuta el cálculo en un solo núcleo; en Linux/Mac puede ponerse en TRUE para acelerar el proceso.
plotErrors(errF, nominalQ=TRUE)
plotErrors(errR, nominalQ=TRUE)
plotErrors()
La función plotErrors()
del paquete
dada2 se utiliza para visualizar los perfiles
de error aprendidos con la función
learnErrors()
.
Descripción:
- Muestra la tasa observada de errores (puntos) en comparación con las
tasas de error esperadas según el modelo (líneas).
- Cada gráfico corresponde a un tipo de sustitución de bases (A→C, A→G,
etc.).
- Sirve como control de calidad para verificar que el modelo de errores
se ajusta correctamente a los datos.
Parámetros comunes:
- err
: objeto de errores obtenido con
learnErrors()
.
- nominalQ=TRUE
: agrega al gráfico las líneas
correspondientes a los valores teóricos de calidad (Q-scores) para
comparación.
Resultado esperado:
Un gráfico donde las curvas del modelo (líneas) se alinean de forma
razonable con los puntos observados. Esto indica que la estimación de
errores es adecuada y puede usarse para la inferencia de variantes de
secuencia exactas (ASVs).
derepFs <- derepFastq(filtFs, verbose=TRUE)
names(derepFs) <- sample.names
save(derepFs, file= "derepFs")
derepRs <- derepFastq(filtRs, verbose=TRUE)
names(derepRs) <- sample.names
save(derepRs, file= "derepRs")
derepFastq()
La función derepFastq()
del paquete
dada2 se utiliza para colapsar lecturas
idénticas en una única secuencia representativa.
Este proceso se llama dereplicación y tiene como objetivo
reducir la redundancia en los datos y acelerar el análisis
posterior.
dadaFs <- dada(derepFs, err=errF, pool = TRUE , multithread=TRUE)
save(dadaFs, file="dadaFs")
dadaRs <- dada(derepRs, err=errR, pool = TRUE , multithread=TRUE)
save(dadaRs, file="dadaRs")
dada()
La función dada()
es el núcleo del paquete
dada2, y se utiliza para realizar la inferencia
de variantes de secuencia exactas (ASVs) a partir de las
lecturas dereplicadas.
En lugar de agrupar lecturas en OTUs por un umbral de
similitud, DADA2 utiliza un modelo estadístico para distinguir errores
de secuenciación de verdaderas diferencias biológicas.
derepFs: lecturas forward previamente dereplicadas.
err=errF: modelo de errores aprendido con learnErrors(), usado para evaluar la probabilidad de que una diferencia entre secuencias sea un error o una variante real.
pool=TRUE: combina todas las muestras para aumentar la sensibilidad en la detección de variantes poco abundantes (si se deja en FALSE, cada muestra se procesa de manera independiente).
multithread=TRUE: permite usar múltiples núcleos para acelerar el cálculo.
Un objeto de clase dada almacena la información de la ASVs a partir de las lecturas dereplicadas. Dentro de cada elemento se encuentra:
$denoised: las secuencias inferidas como variantes reales (ASVs).
$clustering: asignación de cada lectura a su secuencia representativa.
$map: correspondencia entre lecturas originales y ASVs.
$birth_subs / $birth_q: detalles de la primera diferencia de calidad usada en la inferencia.
$err_in / $err_out: tasas de error utilizadas y corregidas en el proceso.
dadaFs[[1]]
dadaRs[[1]]
mean(dadaFs[[1]]$quality)
mean(dadaRs[[1]]$quality)
mergers <- mergePairs(dadaFs, derepFs, dadaRs, derepRs, verbose=TRUE)
save(mergers, file="mergers")
head(mergers[[1]])
mergePairs()
La función mergePairs()
del paquete
dada2 se utiliza para unir las lecturas forward
y reverse de una misma muestra, siempre que presenten una
región solapada suficiente y consistente.
Este paso es crucial en análisis de secuencias de amplicones, ya que la
región resultante es de mayor calidad y cubre toda la zona de
interés.
seqtab <- makeSequenceTable(mergers)
save(seqtab, file="seqtab")
makeSequenceTable()
La función makeSequenceTable()
del paquete
dada2 se utiliza para construir la tabla de
secuencias a partir de los objetos resultantes de
mergePairs()
.
En esta tabla, cada fila corresponde a una muestra y cada columna a una
ASV, de forma análoga a una matriz de conteos.
dim(seqtab)
table(nchar(getSequences(seqtab)))
seq_dis <- table(nchar(getSequences(seqtab)))
barplot(seq_dis,
col = "lightblue",
border = "darkblue",
main = "Distribución de longitudes de ASVs",
xlab = "Longitud de secuencia (bp)",
ylab = "Número de ASVs")
Un paso de control de calidad importante consiste en verificar la
longitud de las secuencias presentes en la tabla
(seqtab
).
Lo habitual es observar una sola longitud dominante, correspondiente a la región de amplicón objetivo (por ejemplo, ~250–300 bp para 16S, dependiendo de los primers usados).
Pueden aparecer unas pocas secuencias con longitudes atípicas (más cortas o más largas), que suelen ser artefactos y pueden eliminarse en pasos posteriores.
Las secuencias que son mucho más largas o más cortas de lo esperado pueden ser el resultado de unión inespecífica de los primers.
Puede eliminar las secuencias con longitudes no objetivo.
seqtab2 <- seqtab[,nchar(colnames(seqtab)) %in% seq(440,466)]
save(seqtab2, file="seqtab2")
Después de construir la tabla de secuencias, es recomendable
conservar únicamente las variantes cuya longitud corresponde al rango
esperado del amplicón (definido por los primers utilizados).
Esto ayuda a eliminar posibles artefactos de secuenciación o
ensamblaje.
colnames(seqtab): obtiene las secuencias (ASVs) como nombres de columna.
nchar(…): calcula la longitud de cada secuencia.
seq(440,466): define el rango esperado de longitudes (por ejemplo, de 440 a 466 bp).
%in%: selecciona solo aquellas secuencias cuya longitud cae dentro de ese rango.
El resultado (seqtab2) es una nueva tabla que incluye únicamente las secuencias con la longitud biológica esperada.
table(nchar(getSequences(seqtab2)))
seq_dis2 <- table(nchar(getSequences(seqtab2)))
barplot(seq_dis2,
col = "lightblue",
border = "darkblue",
main = "Distribución de longitudes de ASVs filtradas",
xlab = "Longitud de secuencia (bp)",
ylab = "Número de ASVs")
seqtab.nochim <- removeBimeraDenovo(seqtab2, method="consensus", multithread=TRUE, verbose=TRUE)
save(seqtab.nochim,file="seqtab.nochim")
dim(seqtab.nochim)
sum(seqtab.nochim)/sum(seqtab2)
removeBimeraDenovo()
La función removeBimeraDenovo()
del paquete
dada2 se utiliza para detectar y eliminar
secuencias quiméricas (chimeras).
Las quimeras son artefactos de PCR que resultan de la combinación de
fragmentos de diferentes secuencias durante la amplificación y por lo
tanto no representan variantes biológicas reales.
seqtab2: tabla de secuencias filtrada por longitud esperada del amplicón.
method=“consensus”: identifica quimeras combinando información de todas las muestras, aumentando la robustez de la detección.
multithread=TRUE: acelera el cálculo usando múltiples núcleos.
verbose=TRUE: muestra información detallada sobre el número de quimeras detectadas y eliminadas.
dna <- DNAStringSet(getSequences(seqtab.nochim))
meansequencelength <- as.data.frame(table(nchar(getSequences(dna))))
meansequencelength$Var1 <- as.numeric(as.character(meansequencelength$Var1))
meansequencelength$total <- meansequencelength$Var1*meansequencelength$Freq
sum(meansequencelength$total)/sum(meansequencelength$Freq)
DNAStringSet()
La función DNAStringSet()
del paquete
Biostrings se utiliza para crear un objeto
especializado que almacena conjuntos de secuencias de
ADN.
Este tipo de objeto es mucho más eficiente que un simple vector de
caracteres, ya que está optimizado para trabajar con datos biológicos y
permite aplicar fácilmente funciones de manipulación y análisis de
secuencias.
getSequences(seqtab.nochim): extrae todas las secuencias únicas (ASVs) de la tabla sin quimeras.
getN <- function(x) sum(getUniques(x))
track <- cbind(out, sapply(dadaFs, getN), sapply(dadaRs, getN), sapply(mergers, getN),rowSums(seqtab.nochim))
Para evaluar la eficiencia del pipeline de DADA2, es recomendable llevar un control del número de lecturas que se mantienen en cada etapa del procesamiento.
colnames(track) <- c("input", "filtered", "denoisedF", "denoisedR", "merged", "nonchim")
rownames(track) <- sample.names
head(track)
Para mejorar la interpretación de la matriz track
, se
añaden nombres descriptivos a las columnas (etapas del pipeline) y a las
filas (muestras).
taxa <- assignTaxonomy(seqtab.nochim, "ruta/a/silva_nr_v132_train_set.fa.gz", multithread=TRUE)
assignTaxonomy()
La función assignTaxonomy()
del paquete
dada2 se utiliza para asignar taxonomía a las
variantes de secuencia exactas (ASVs) obtenidas después del
filtrado, corrección de errores y eliminación de quimeras.
Descripción:
- Compara cada secuencia de la tabla (seqtab.nochim
) contra
una base de datos de referencia taxonómica (por
ejemplo, SILVA, RDP o
Greengenes).
- Utiliza un clasificador basado en la probabilidad Naïve Bayesian
classifier, entrenado con secuencias anotadas.
- Devuelve un objeto donde cada ASV queda anotada con su taxonomía
jerárquica:
Reino → Filo → Clase → Orden → Familia → Género
Parámetros principales:
- seqtab.nochim
: tabla de secuencias sin quimeras sobre la
cual se asignará la taxonomía.
- "ruta/a/silva_nr_v132_train_set.fa.gz"
: archivo de
referencia previamente entrenado (en este ejemplo, SILVA v132).
- multithread=TRUE
: permite usar múltiples núcleos para
acelerar el proceso.
Resultado esperado:
- Una matriz o data.frame donde:
- Cada fila corresponde a un ASV.
- Cada columna representa un nivel taxonómico.
- Las celdas contienen la clasificación más probable para cada
secuencia.
taxa <- addSpecies(taxa, "ruta/a/silva_species_assignment_v132.fa.gz")
addSpecies()
La función addSpecies()
del paquete
dada2 se utiliza para afinar la asignación
taxonómica hasta el nivel de especie, siempre que la base de
datos de referencia lo permita.
Descripción:
- Toma como entrada el objeto taxa
previamente generado con
assignTaxonomy()
.
- Compara cada ASV contra una base de datos que contiene
secuencias de referencia a nivel de especie.
- Asigna la especie más probable cuando existe una coincidencia exacta o
muy cercana.
Parámetros principales:
- taxa
: objeto de taxonomía obtenido con
assignTaxonomy()
.
- "ruta/a/silva_species_assignment_v132.fa.gz"
: archivo de
referencia con asignaciones a nivel de especie (en este caso, de la base
SILVA v132).
Resultado esperado:
- El objeto taxa
se actualiza con una columna adicional
llamada Especie, que contiene la anotación más probable
para cada ASV.
- Si no hay coincidencia confiable, la celda queda vacía
(NA
).
Importancia:
La asignación hasta especie puede ser muy útil para estudios clínicos o
ecológicos detallados, aunque debe interpretarse con precaución ya que
depende de la calidad y cobertura de la base de datos de referencia.
save(taxa, file="taxa")
La base de datos para la asignación de taxonomía pueden descargarse
desde este link.
Puede explorar las versión mas reciente de la base de datos SILVA aquí.
Por razones de tiempo la asignación taxonómica no se realizará durante el taller.