Evidencia 1 - Análisis de variantes de SARS-CoV-2

Nombre: Sebastian Villegas Olaya
Matrícula: A01714719
Materia: Biología Computacional (BT1013)
Profesor: Gerardo Javier Alanis Funes
Fecha: 2026-05-01

Introducción

En este trabajo se analizan secuencias de variantes de SARS-CoV-2 obtenidas desde NCBI. Las variantes usadas en el análisis son Wuhan, Alpha, Beta, Gamma y Mu.

El objetivo es calcular la longitud de cada secuencia, comparar la composición de bases de ADN, obtener el porcentaje GC y generar la hebra contrasentido de cada variante.

Código en R

setwd("~/Proyecto Evidencia 1 Biologia Computacional")

library(seqinr)
library(Biostrings)
library(ggplot2)

# Leer un archivo FASTA con varias secuencias
leer_fasta_multiple <- function(archivo) {
  secuencias <- read.fasta(archivo, seqtype = "DNA", as.string = TRUE)
  
  lista_secuencias <- lapply(secuencias, function(x) {
    toupper(as.character(x))
  })
  
  return(lista_secuencias)
}

tamano_dna <- function(secuencia) {
  nchar(secuencia)
}

porcentaje_bases <- function(secuencia) {
  letras <- strsplit(toupper(secuencia), "")[[1]]
  
  total_validas <- sum(letras %in% c("A", "T", "C", "G"))
  
  if (total_validas == 0) {
    print("No hay bases válidas.")
    return(NULL)
  }
  
  a <- sum(letras == "A") / total_validas * 100
  t <- sum(letras == "T") / total_validas * 100
  c <- sum(letras == "C") / total_validas * 100
  g <- sum(letras == "G") / total_validas * 100
  
  print(paste("A:", round(a, 2), "%"))
  print(paste("T:", round(t, 2), "%"))
  print(paste("C:", round(c, 2), "%"))
  print(paste("G:", round(g, 2), "%"))
  
  resultados <- data.frame(
    Base = c("A", "T", "C", "G"),
    Porcentajes = c(A = a, T = t, C = c, G = g)
  )
  
  return(resultados)
}

calcular_gc <- function(secuencia) {
  lineas <- strsplit(toupper(secuencia), "")[[1]]
  total_validas <- sum(lineas %in% c("G", "C", "A", "T"))
  
  gc <- sum(lineas %in% c("G", "C"))
  porcentaje_gc <- (gc / total_validas) * 100
  
  print("Porcentaje de GC:")
  print(paste(round(porcentaje_gc, 4), "%"))
  print("Conteo de GC:")
  print(gc)
  
  return(porcentaje_gc)
}

hebra_contrasentido <- function(secuencia) {
  secuencia_dna <- DNAString(secuencia)
  as.character(reverseComplement(secuencia_dna))
}

crear_grafica_bases <- function(resultados_composicion) {
  df <- do.call(rbind, lapply(names(resultados_composicion), function(nombre) {
    df_temp <- resultados_composicion[[nombre]]
    df_temp$Variante <- nombre
    df_temp
  }))
  
  ggplot(df, aes(x = Variante, y = Porcentajes, fill = Base)) +
    geom_bar(stat = "identity", position = "dodge") +
    geom_text(aes(label = paste0(round(Porcentajes, 2), "%")),
              position = position_dodge(width = 0.9),
              vjust = -0.5,
              size = 3) +
    labs(
      title = "Composición de bases por variante",
      x = "Variante",
      y = "Porcentaje (%)",
      fill = "Base"
    ) +
    theme_minimal()
}

crear_grafica_gc <- function(resultados_gc) {
  df_gc <- data.frame(
    Variante = names(resultados_gc),
    GC = unlist(resultados_gc)
  )
  
  ggplot(df_gc, aes(x = Variante, y = GC, fill = Variante)) +
    geom_bar(stat = "identity") +
    geom_text(aes(label = paste0(round(GC, 2), "%")),
              vjust = -0.5,
              size = 4) +
    labs(
      title = "Contenido GC por variante",
      x = "Variante",
      y = "Contenido GC (%)",
      fill = "Variante"
    ) +
    theme_minimal()
}

analizar_variantes <- function(archivo) {
  
  secuencias <- leer_fasta_multiple(archivo)
  
  resultados_composicion <- list()
  resultados_gc <- list()
  longitudes <- list()
  secuencias_contrasentido <- list()
  
  for (nombre in names(secuencias)) {
    
    secuencia <- secuencias[[nombre]]
    
    cat("Analizando variante:", nombre, "\n")
    
    longitudes[[nombre]] <- tamano_dna(secuencia)
    cat("Longitud:", longitudes[[nombre]], "bases\n")
    
    composicion <- porcentaje_bases(secuencia)
    resultados_composicion[[nombre]] <- composicion
    
    gc_contenido <- calcular_gc(secuencia)
    resultados_gc[[nombre]] <- gc_contenido
    
    contrasentido <- hebra_contrasentido(secuencia)
    secuencias_contrasentido[[nombre]] <- contrasentido
    
    cat("Hebra contrasentido de", nombre, "\n")
    primeros <- paste(strsplit(substring(contrasentido, 1, 15), "")[[1]], collapse = " ")
    ultimos <- paste(strsplit(substring(contrasentido, nchar(contrasentido) - 14, nchar(contrasentido)), "")[[1]], collapse = " ")
    cat(primeros, "...", ultimos, "\n")
    
    cat(rep("-", 50), "\n")
  }
  
  return(list(
    composicion = resultados_composicion,
    gc = resultados_gc,
    longitudes = longitudes,
    contrasentido = secuencias_contrasentido
  ))
}

archivo_covid <- "Secuencias.fasta"

resultados <- analizar_variantes(archivo_covid)
## Analizando variante: Wuhan 
## Longitud: 29903 bases
## [1] "A: 29.94 %"
## [1] "T: 32.08 %"
## [1] "C: 18.37 %"
## [1] "G: 19.61 %"
## [1] "Porcentaje de GC:"
## [1] "37.9728 %"
## [1] "Conteo de GC:"
## [1] 11355
## Hebra contrasentido de Wuhan 
## T T T T T T T T T T T T T T T ... G T A T A A A C C T T T A A T 
## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
## Analizando variante: Alpha 
## Longitud: 29884 bases
## [1] "A: 29.87 %"
## [1] "T: 32.14 %"
## [1] "C: 18.35 %"
## [1] "G: 19.64 %"
## [1] "Porcentaje de GC:"
## [1] "37.9868 %"
## [1] "Conteo de GC:"
## [1] 11306
## Hebra contrasentido de Alpha 
## N N N N N N N N N N N N N N N ... N N N N N N N N N N N N N N N 
## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
## Analizando variante: Beta 
## Longitud: 29879 bases
## [1] "A: 29.9 %"
## [1] "T: 32.11 %"
## [1] "C: 18.34 %"
## [1] "G: 19.64 %"
## [1] "Porcentaje de GC:"
## [1] "37.9884 %"
## [1] "Conteo de GC:"
## [1] 11025
## Hebra contrasentido de Beta 
## N N N N N N N N N N N N N N N ... N N N N N N N N N N N N N N N 
## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
## Analizando variante: Gamma 
## Longitud: 29868 bases
## [1] "A: 29.88 %"
## [1] "T: 32.14 %"
## [1] "C: 18.37 %"
## [1] "G: 19.61 %"
## [1] "Porcentaje de GC:"
## [1] "37.9788 %"
## [1] "Conteo de GC:"
## [1] 11342
## Hebra contrasentido de Gamma 
## T T T G T C A T T C T C C T A ... G T A T A A A C C T T T A A T 
## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
## Analizando variante: Mu 
## Longitud: 29742 bases
## [1] "A: 29.89 %"
## [1] "T: 31.87 %"
## [1] "C: 18.56 %"
## [1] "G: 19.68 %"
## [1] "Porcentaje de GC:"
## [1] "38.239 %"
## [1] "Conteo de GC:"
## [1] 7496
## Hebra contrasentido de Mu 
## T C A C T G T A C A C T C G A ... G T T G G T T G G T T T G T T 
## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Longitud de las secuencias

tabla_longitudes <- data.frame(
  Variante = names(resultados$longitudes),
  Longitud = unlist(resultados$longitudes)
)

tabla_longitudes

Porcentaje GC de cada variante

tabla_gc <- data.frame(
  Variante = names(resultados$gc),
  Porcentaje_GC = round(unlist(resultados$gc), 4)
)

tabla_gc

Gráfica de composición de bases

print(crear_grafica_bases(resultados$composicion))

Interpretación de la gráfica de bases

En la gráfica de composición de bases se comparan los porcentajes de adenina, timina, citosina y guanina en cada variante del SARS-CoV-2.

Se puede observar que las variantes tienen una composición de bases parecida, lo cual tiene sentido porque todas pertenecen al mismo virus. Sin embargo, pueden aparecer pequeñas diferencias entre variantes debido a mutaciones acumuladas en su genoma.

Gráfica de contenido GC

print(crear_grafica_gc(resultados$gc))

Interpretación de la gráfica GC

La gráfica de contenido GC muestra el porcentaje de guanina y citosina presente en cada variante.

El porcentaje GC permite comparar qué proporción del genoma está formada por estas dos bases. Si los valores son parecidos, significa que la estructura general del genoma viral se mantiene relativamente estable entre variantes. Si hay pequeñas diferencias, estas pueden relacionarse con cambios o mutaciones en la secuencia.

Secuencias contrasentido

for (nombre in names(resultados$contrasentido)) {
  cat("Variante:", nombre, "\n")
  cat("Primeras 50 bases de la hebra contrasentido:\n")
  cat(substring(resultados$contrasentido[[nombre]], 1, 50), "\n\n")
}
## Variante: Wuhan 
## Primeras 50 bases de la hebra contrasentido:
## TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTGTCATTCTCCTAAGAAG 
## 
## Variante: Alpha 
## Primeras 50 bases de la hebra contrasentido:
## NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN 
## 
## Variante: Beta 
## Primeras 50 bases de la hebra contrasentido:
## NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN 
## 
## Variante: Gamma 
## Primeras 50 bases de la hebra contrasentido:
## TTTGTCATTCTCCTAAGAAGCTATTAAAATCACATGGGGTTAGCACTACT 
## 
## Variante: Mu 
## Primeras 50 bases de la hebra contrasentido:
## TCACTGTACACTCGATCGTACTCCGCGTGGCCTCGGTGAAAATGTGGTGG

Conclusión

En este análisis se utilizaron herramientas de R para estudiar variantes de SARS-CoV-2 a partir de un archivo multi-FASTA. Se calculó la longitud de cada secuencia, la composición de bases, el porcentaje GC y la hebra contrasentido.

Este tipo de análisis es útil en biología computacional porque permite comparar secuencias genéticas de forma rápida y organizada. Además, ayuda a identificar diferencias entre variantes virales que pueden estar relacionadas con mutaciones.