Casos prácticos: Fundamentos de programación y acceso a base de datos en R

#Caso práctico 1
Según las investigaciones de Mark E. Curtis, cada giro completo de la doble hélice del ADN mide 21 Å de ancho por 34 Å de largo; 34 y 21 son dos números consecutivos en la sucesión de Fibonacci. Por lo tanto, su cociente, 1.6190476, aproxima de cerca la Razón Áurea φ=1.6180339… Se pide: a) Implementad en R una función que, dado un valor n, muestre los valores de la serie de Fibonacci hasta ese valor determinado. b) ¿Para qué valores de n localizamos, en la serie de Fibonacci, las medidas de la doble hélice de la molécula de ADN? c) Complementad el código del apartado a) añadiendo una nueva función (o las instrucciones que correspondan en la función creada anteriormente) de manera que, para un determinado valor n, muestre las proporciones sucesivas de los valores de la serie de Fibonacci. ¿A partir de qué valor de n, esta proporción se va aproximando a la Razón Áurea?

#Apartado a)
fibo<-function(n) {
  lista <- c(0,1)
  i=2
  for (i in i:(n-1)){
    lista[i+1] <-lista[i]+lista[i-1]
  }
return(lista)
}
resultados <- fibo(10)
print(resultados)
##  [1]  0  1  1  2  3  5  8 13 21 34
#Apartado b)
fibo(9) #El valor 21 corresponde n=9
## [1]  0  1  1  2  3  5  8 13 21
fibo(10) #El valor 34 corresponde n=10
##  [1]  0  1  1  2  3  5  8 13 21 34
#Apartado c)
aurea <- function(n) {
  num <- fibo(n)
  rel <- numeric(length(num) - 1)
    for (i in 2:length(num)) {
    rel[i - 1] <- num[i] / num[i - 1]
  }
    return(rel)
}
raurea<-aurea(10) #A partir del valor de n=10, esta proporción es muy próxima al valor de la relación áurea
raurea
## [1]      Inf 1.000000 2.000000 1.500000 1.666667 1.600000 1.625000 1.615385
## [9] 1.619048

#Caso práctico 2
La secuencia de ADN de un individuo contiene información genética de este. Actualmente, existen técnicas que permiten realizar esta secuenciación y aportar datos para investigar el comportamiento de diferentes tipos de organismos biológicos. Se pide generar una secuencia de ADN y calcular su inverso y su complementario.

#Función para generar cadena ADN
cadena_ADN<-function(n) {
  bases<-c("A", "C", "G", "T")
  muestra<-sample(bases, n, replace=TRUE)
  return(paste(muestra, collapse = ""))
}
lista3<-cadena_ADN(10)
print(lista3)
## [1] "CGCATTTGGG"
#Para invertir la cadena
secuencia<-cadena_ADN(10)
cadena_invertida<- rev(strsplit(secuencia, "")[[1]])
cadena_invertida <- paste(cadena_invertida, collapse = "")
secuencia
## [1] "TTCGTCACGC"
cadena_invertida
## [1] "CGCACTGCTT"
#Para obtener la complementaria
secuencia <- "ACGACTAG"
cadena_c <- function(secuencia) {
  cadena <- strsplit(secuencia, "")[[1]]
  for (i in seq_along(cadena)) {
    if (cadena[i] == "A") {
      cadena[i] <- "T"
    } else if (cadena[i] == "T") {
      cadena[i] <- "A"
    } else if (cadena[i] == "C") {
      cadena[i] <- "G"
    } else if (cadena[i] == "G") {
      cadena[i] <- "C"
    }
  }
  return(paste(cadena, collapse = ""))
}

cadena_complementaria <- cadena_c(secuencia)
print(secuencia)
## [1] "ACGACTAG"
print(cadena_complementaria)
## [1] "TGCTGATC"

#Caso práctico 3
Supongamos que pretendemos gestionar la información de una base de datos de pacientes de un hospital. En principio, disponemos de dos tablas, pacientes y registros_médicos.
De la tabla pacientes, disponemos de los siguientes datos: pacientes (nombre, edad, género, condición_médica) (‘Paciente1’, 45, ‘Femenino’, ‘Diabetes’), (‘Paciente2’, 32, ‘Masculino’, ‘Hipertensión’), (‘Paciente3’, 28, ‘Femenino’, ‘Sano’), (‘Paciente4’, 55, ‘Masculino’, ‘Hipertensión’), (‘Paciente5’, 40, ‘Femenino’, ‘Asma’).
De la tabla registros_médicos, disponemos de los siguientes datos: registros_médicos (paciente_id, fecha, nivel_glucosa) (1, ‘2023-08-01’, 125.5), (2, ‘2023-08-01’, 140.2), (3, ‘2023-08-01’, 95.8), (4, ‘2023-08-01’, 160.6), (5, ‘2023-08-01’, 110.9).
Se pide utilizar las instrucciones de acceso a bases de datos para resolver las siguientes cuestiones (es importante recordar cargar los paquetes RSQLite, dplyr y, también, ggplot2.): 1) Cread la base de datos (Hospital), las tablas y los registros correspondientes y la conexión desde R. 2) Mostrad pacientes con una condición médica específica (por ejemplo, diabetes). 3) Calculad estadísticas descriptivas de los niveles de glucosa en sangre. 4) Obtened los registros médicos de pacientes con hipertensión y sus estadísticas de glucosa. 5) Calculad la edad promedio de pacientes con asma por género. 6) Cread un gráfico de barras para mostrar la distribución de género en pacientes con diabetes.

library(RSQLite)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
#Conectar a la base de datos SQLite
con<-dbConnect(SQLite(), "hospital.db")
#Apartado 1: Generar ambas tablas
pacientes<-data.frame(
  nombre=c("Paciente1", "Paciente2", "Paciente3", "Paciente4", "Paciente5"),
  edad=c(45, 32, 28, 55, 40),
  género=c("Femenino", "Masculino", "Femenino", "Masculino","Femenino"),
  condición_médica=c("Diabetes", "Hipertensión", "Sano", "Hipertensión", "Asma")
)
registros_médicos<-data.frame(
  paciente_id=c(1, 2, 3, 4, 5),
  fecha=c("2023-08-01", "2023-08-01", "2023-08-01", "2023-08-01", "2023-08-01"),
  nivel_glucosa=c(125.5, 140.2, 95.8, 160.6, 110.9)
)
dbWriteTable(con, "pacientes", pacientes, overwrite=TRUE)
dbWriteTable(con, "registros_médicos", registros_médicos, overwrite=TRUE)
head(pacientes)
##      nombre edad    género condición_médica
## 1 Paciente1   45  Femenino         Diabetes
## 2 Paciente2   32 Masculino     Hipertensión
## 3 Paciente3   28  Femenino             Sano
## 4 Paciente4   55 Masculino     Hipertensión
## 5 Paciente5   40  Femenino             Asma
head(registros_médicos)
##   paciente_id      fecha nivel_glucosa
## 1           1 2023-08-01         125.5
## 2           2 2023-08-01         140.2
## 3           3 2023-08-01          95.8
## 4           4 2023-08-01         160.6
## 5           5 2023-08-01         110.9
#Apartado 2: Buscar pacientes con diabetes
pacientes_diabetes<-dbGetQuery(con, "SELECT nombre FROM pacientes WHERE condición_médica = 'Diabetes'")
pacientes_diabetes
##      nombre
## 1 Paciente1
#Apartado 3: variables estadísticas de los niveles de glucosa
glucosa<-dbGetQuery(con, "SELECT AVG(nivel_glucosa) AS media_glucosa,
                     MAX(nivel_glucosa) AS max_glucosa,
                     MIN(nivel_glucosa) AS min_glucosa,
                     STDEV(nivel_glucosa) AS sd_glucosa FROM registros_médicos")
glucosa
##   media_glucosa max_glucosa min_glucosa sd_glucosa
## 1         126.6       160.6        95.8   25.18581
#Apartado 4: Pacientes con hipertensión y ver sus glucosas
pacientes_hipertensión <- dbGetQuery(con, "SELECT *
FROM registros_médicos r
JOIN pacientes p ON r.paciente_id= p.rowid
WHERE p.condición_médica ='Hipertensión'")
pacientes_hipertensión
##   paciente_id      fecha nivel_glucosa    nombre edad    género
## 1           2 2023-08-01         140.2 Paciente2   32 Masculino
## 2           4 2023-08-01         160.6 Paciente4   55 Masculino
##   condición_médica
## 1     Hipertensión
## 2     Hipertensión
glucosa_hipertensión<-dbGetQuery(con, "SELECT AVG(nivel_glucosa) AS media_glucosa,
                     MAX(nivel_glucosa) AS max_glucosa,
                     MIN(nivel_glucosa) AS min_glucosa,
                     STDEV(nivel_glucosa) AS sd_glucosa
                     FROM (
                         SELECT nivel_glucosa
                         FROM registros_médicos r
                         JOIN pacientes p ON r.paciente_id = p.rowid
                         WHERE p.condición_médica = 'Hipertensión'
                     ) AS subquery")
glucosa_hipertensión
##   media_glucosa max_glucosa min_glucosa sd_glucosa
## 1         150.4       160.6       140.2   14.42498
#Apartado 5: Edad promedio de pacientes con asma por género.
edad_asma<-dbGetQuery(con, "SELECT género, AVG(edad) AS edad_promedio FROM pacientes WHERE condición_médica='Asma' GROUP BY género")
edad_asma
##     género edad_promedio
## 1 Femenino            40
#Apartado 6: Gráfico de barras para mostrar la distribución de género en pacientes con diabetes.
genero_diabetes<-dbGetQuery(con, "SELECT género, COUNT(*) AS número FROM pacientes WHERE condición_médica='Diabetes' GROUP BY género")
genero_diabetes
##     género número
## 1 Femenino      1
ggplot(genero_diabetes, aes(x=género, y=número, fill=género)) + 
  geom_bar(stat = "identity") +
  labs(title = "Distribución del género en pacientes con diabetes", x = "Género", y = "Número") +
theme_classic()