📘 Funciones útiles y REGEX

En esta sesión, el objetivo es entender expresiones regulares y la creación de funciones propias. Adicionalmente se revisan funciones útiles como:

  1. Concatenación de texto usando las funciones paste() y paste0().
  2. Generación de aleatoriedad controlada usando set.seed() y sample().
  3. Encontrar posiciones específicas de un patrón de caracteres usando grep().

Uso de set.seed() y sample() para letras aleatorias

La función set.seed() se usa para fijar la semilla de aleatoriedad, lo que asegura que los resultados sean reproducibles. La función sample() permite extraer muestras aleatorias.

set.seed(123)  # Fija la semilla para resultados reproducibles
# Ejemplo 1:
sample(LETTERS, 5)  # Toma 5 letras mayúsculas al azar
## [1] "O" "S" "N" "C" "J"
# Resultado: "W" "I" "F" "O" "X"

Ejemplo 2: Crear nombres de archivos numerados

paste0("archivo_", 1:5, ".csv")
## [1] "archivo_1.csv" "archivo_2.csv" "archivo_3.csv" "archivo_4.csv"
## [5] "archivo_5.csv"
# Resultado: "archivo_1.csv" "archivo_2.csv" ... "archivo_5.csv"

Ejemplo 3: Unir texto y resultados numéricos

temperatura <- 25
paste("La temperatura es", temperatura, "grados.")
## [1] "La temperatura es 25 grados."
# Resultado: "La temperatura es 25 grados."

Ejemplo 4: Construir nombres de columnas con separador personalizado

paste(LETTERS[1:4], 1:4, sep = "_")
## [1] "A_1" "B_2" "C_3" "D_4"
# Resultado: "A_1" "B_2" "C_3" "D_4"

Ejemplo 5: Usar collapse para unir todo en una sola cadena

Esta opción permite unir varios elementos en una sola cadena de texto

paste(c("A", "B", "C"), collapse = "-")
## [1] "A-B-C"
# Resultado: "A-B-C"

Ejercicio: Generar nombres de genes simulados

Este ejemplo muestra cómo construir nombres simulados de genes, combinando paste0() y sample() para ilustrar cómo crear datos similares a los utilizados en bioinformática.

Usar bucles para ahorrar tiempo y practicar lo visto en sesiones pasadas

set.seed(101)
# Opcion 1: for loop
random_letters <- vector()
for (ii in 1:6) {
  random_letters[ii] <- paste(sample(LETTERS, 4), collapse = "")
}
# Opcion 2: sapply
random_letters <- sapply(1:6, function(x) paste(sample(LETTERS, 4), collapse = ""))

# Generar números aleatorios para sufijos numéricos
random_numbers <- sample(1:30, 6)

# Simular genes tipo ISG, IRF y orf
ISG_genes <- paste0("ISG", random_numbers)
IRF_genes <- paste0("IRF", random_numbers)
orf_genes <- paste0("C", random_letters, "orf", random_numbers)

# Otros genes con fines didacticos
otros_genes <- c("TISG", "PISG12", "TIRFB", "123orfAA", "CCorf12", "FGorf")

# Unir todos los genes y mezclarlos
genes <- c(ISG_genes, IRF_genes, orf_genes, otros_genes)
lista_genes <- sample(genes)

# Mostrar resultado
lista_genes
##  [1] "IRF14"      "CCJTBorf14" "CTFXGorf28" "CCorf12"    "CQLCIorf16"
##  [6] "FGorf"      "ISG13"      "IRF28"      "IRF22"      "ISG16"     
## [11] "CTNHXorf13" "TIRFB"      "PISG12"     "CZKUXorf1"  "123orfAA"  
## [16] "ISG28"      "TISG"       "ISG1"       "IRF16"      "ISG22"     
## [21] "IRF1"       "IRF13"      "ISG14"      "CJZIEorf22"

Expresiones regulares básicas


Ejercicios con grep() y expresiones regulares

La función grep() busca patrones en vectores de texto. Por defecto, devuelve las posiciones donde el patrón se encuentra. Puedes usarlo junto con expresiones regulares para hacer búsquedas más avanzadas. Por ejemplo, me interesa saber si mi paciente tiene una respues antiviral efectiva. Para esto, debo identificar los genes de respuesta a interferon, estos empiezan con “IRF” e “ISG”

# Buscar todas las posiciones que contienen "IRF" en cualquier parte de la cadena.
grep("IRF", lista_genes)
## [1]  1  8  9 12 19 21 22
# Usar los resultados para seleccionar elementos que contienen IRF
lista_genes[grep("IRF", lista_genes)] # TIRFB tambien cumple con la condicion
## [1] "IRF14" "IRF28" "IRF22" "TIRFB" "IRF16" "IRF1"  "IRF13"
# Buscar solo las que **empiezan con** "IRF"
lista_genes[grep("^IRF", lista_genes)]
## [1] "IRF14" "IRF28" "IRF22" "IRF16" "IRF1"  "IRF13"
# Buscar solo las que **empiezan con** "ISG"
lista_genes[grep("^ISG", lista_genes)]
## [1] "ISG13" "ISG16" "ISG28" "ISG1"  "ISG22" "ISG14"
# Buscar genes que empiecen con "ISG" o "IRF"
lista_genes[grep("^ISG|^IRF", lista_genes)]  # el operador | actúa como una unión (OR)
##  [1] "IRF14" "ISG13" "IRF28" "IRF22" "ISG16" "ISG28" "ISG1"  "IRF16" "ISG22"
## [10] "IRF1"  "IRF13" "ISG14"
# Buscar genes que terminan con "28"
lista_genes[grep("28$", lista_genes)]  # $ indica "termina con"
## [1] "CTFXGorf28" "IRF28"      "ISG28"
# Buscar solo conincidencias exactas de "ISG"
lista_genes[grep("^ISG$", lista_genes)] # Ninguno cumple la condicion
## character(0)
# Genes que contienen "orf" no estan caracterizados. Recomendable eliminarlos previo al analisis
lista_genes[grep("orf", lista_genes)] # Esto tambien arroja genes, como 123orfAA, CCorf12 y FGorf
## [1] "CCJTBorf14" "CTFXGorf28" "CCorf12"    "CQLCIorf16" "FGorf"     
## [6] "CTNHXorf13" "CZKUXorf1"  "123orfAA"   "CJZIEorf22"
# Buscar genes donde "orf" va seguido de un número.
lista_genes[grep("orf[0-9]", lista_genes)] # Esto tambien arroja genes, como CCorf12
## [1] "CCJTBorf14" "CTFXGorf28" "CCorf12"    "CQLCIorf16" "CTNHXorf13"
## [6] "CZKUXorf1"  "CJZIEorf22"
# La expresion definitiva seria buscar genes que tienen al menos 4 letras antes de "orf" y luego un número
lista_genes[grep("[A-Z]{4}orf[0-9]", lista_genes)]
## [1] "CCJTBorf14" "CTFXGorf28" "CQLCIorf16" "CTNHXorf13" "CZKUXorf1" 
## [6] "CJZIEorf22"
# Variante de grep: grepl devuelve valores logicos en lugar de posiciones
grepl("[A-Z]{4}orf[0-9]", lista_genes)
##  [1] FALSE  TRUE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
## [13] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
# Usamos el vector logico en lugar del vector numerico para seleccionar valores
lista_genes[grepl("[A-Z]{4}orf[0-9]", lista_genes)]
## [1] "CCJTBorf14" "CTFXGorf28" "CQLCIorf16" "CTNHXorf13" "CZKUXorf1" 
## [6] "CJZIEorf22"
# Podemos invertir los valores logicos con `!` para eliminar genes no deseados
lista_genes[!grepl("[A-Z]{4}orf[0-9]", lista_genes)]
##  [1] "IRF14"    "CCorf12"  "FGorf"    "ISG13"    "IRF28"    "IRF22"   
##  [7] "ISG16"    "TIRFB"    "PISG12"   "123orfAA" "ISG28"    "TISG"    
## [13] "ISG1"     "IRF16"    "ISG22"    "IRF1"     "IRF13"    "ISG14"

Ejemplos adicionales

correo <- c("eric.com", "TallerR@gmail.com", "insituto.mexicano.mx", "contraseña")

# . (punto) significa cualquier carácter, por lo tanto esto detecta todo
correo[grep(".", correo)]
## [1] "eric.com"             "TallerR@gmail.com"    "insituto.mexicano.mx"
## [4] "contraseña"
# Para buscar un punto literal, se necesita escapar con \.
correo[grep("\\.", correo)]
## [1] "eric.com"             "TallerR@gmail.com"    "insituto.mexicano.mx"

Crear nuestras propias funciones en R

Una función en R permite encapsular código reutilizable. Aquí hay ejemplos sencillos para practicar la creación de funciones.

Ejemplo 1: Función saludo() con argumento opcional

saludo <- function(nombre = "amigo") {
  mensaje <- paste("Hola", nombre)
  return(mensaje)
}

saludo("Ana")
## [1] "Hola Ana"
# [1] "Hola Ana"

saludo()
## [1] "Hola amigo"
# [1] "Hola amigo"

Ejemplo 2: Función respuesta_automatica() con condicionales

respuesta_automatica <- function(hoy){
  if (hoy == "viernes") {
    mensaje <- "Lo vemos el lunes"
  } else if (hoy %in% c("sabado","domingo")){
    mensaje <- "Hoy no trabajo"
  } else {
    mensaje <- "De inmediato"
  }
  return(mensaje)
}

respuesta_automatica(hoy = "lunes")
## [1] "De inmediato"
# [1] "De inmediato"