Workbooks de la asignatura Aprendizaje Supervisado I
Author
Javier Álvarez Liébana
1 Clase 1
1.1 🐣 Caso práctico I: anscombe
En el paquete {datasets} se encuentra el dataset conocido como cuarteto de Anscombe, un dataset que cuenta con 4 conjuntos de datos, cada uno de ellos cuenta con 11 observaciones de una variable x y otra y.
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.3 ✔ tidyr 1.3.1
✔ purrr 1.0.2
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
Si te fijas todos los datasets tienen los mismos momentos muestrales … ¿serán el mismo dataset desordenado? Visualiza los 4 datasets en el mismo gráfico mediante un diagrama de dispersión con su ajuste de regresión
Code
ggplot(anscombe_tidy, aes(x = x, y = y, color = dataset)) +geom_point(size =3, alpha =0.7) +geom_smooth(method ="lm", se =FALSE) + ggthemes::scale_color_colorblind() +facet_wrap(~dataset) +theme_minimal()
`geom_smooth()` using formula = 'y ~ x'
Por suerte o por desgracia no todo son matemáticas: antes de pensar que modelo es mejor para nuestros datos, es importantísimo realizar un análisis exploratorio de los mismos (incluyendo visualización)
Rows: 100 Columns: 8
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (3): Genero, EstadoCivil, EstadoSalud
dbl (5): ID, Edad, TiempoEspera, GradoSatisfaccion, NumeroVisitas
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Convierte de manera adecuada la variable estado_salud a cualitativa ORDINAL
Code
datos <- datos |>mutate(estado_salud =factor(estado_salud, levels =c("Malo", "Regular", "Bueno", "Excelente"),ordered =TRUE))
2.1.2 Pregunta 2
Haz uso de table() para calcular la tabla de frecuencias de genero y estado_civil
Code
table(datos$genero)table(datos$estado_civil)
2.1.3 Pregunta 3
Calcula la tabla de frecuencias de las ORDINALES y piensa si ahora puedes añadir algo más a la tabla de frecuencias). Tras ello usa el código más sencillo para responder a: ¿cuántas personas tienen un estado de salud regular (o peor)?
Code
freq_estado_salud <- datos |>count(estado_salud) |>rename(frecuencia_abs = n) |>mutate(frecuencia_rel = frecuencia_abs/sum(frecuencia_abs),frecuencia_acum_abs =cumsum(frecuencia_abs),frecuencia_acum_rel =cumsum(frecuencia_rel))# Se ve dentro de la tabla. Hay 44+15 = 59 personas con un estado de salud malo o regular. # Con códigodatos |>count(estado_salud <="Regular")
2.1.4 Pregunta 4
Si te fijas una de las modalidades es totalmente anecdótica (solo 1 Excelente). Sería conveniente recategorizar la categoría Excelente: siempre que detecte Excelente, lo debe recategorizar a Bueno (criterio general: las categorías deben contener al menos un 5% de los individuos de toda la muestra).
Code
datos <- datos |>mutate(estado_salud =if_else(estado_salud =="Excelente", "Bueno", estado_salud),# ojo: hay que redefinir los niveles de la cualitativa# ya que ha dejado de ser factor (veremos un día el paquete forcats para esto)estado_salud =factor(estado_salud, levels =c("Malo", "Regular", "Bueno"),ordered =TRUE))
2.1.5 Pregunta 5
Calcula la media, mediana, rango intercuartílico y desviación típica de grado de satisfacción desagregado por sexo.
Exporta los resultados anteriores (resumen) en un archivo resumen.csv. En lugar de un read_csv() vamos a usar write_csv(tabla, file = "ruta")
Code
# importado como csvwrite_csv(resumen, file ="./resumen.csv")
2.1.7 Pregunta 7
Crear un diagrama de barras para la variable género. ¿Cómo podríamos decirle que cada barra (es decir, para cada modalidad de género) sea de un color (de relleno)?
Code
ggplot(datos) +# dentro de aes() para que dependa de la tablageom_bar(aes(x = genero, fill = genero))
2.1.8 Pregunta 8
Crear desde cero un diagrama de barras, con ajustes personalizados para la variable estado de salud
Code
# Estado de salud (ahora el orden importa)ggplot(datos) +geom_bar(aes(x = estado_salud, fill = estado_salud), alpha =0.75) + ggthemes::scale_fill_colorblind() +labs(title ="Diagrama de barras de la variable estado salud", x ="Categoría", y ="Frecuencia absoluta",fill ="Categoría") +theme_minimal()
Fíjate que si no tuviésemos la variable como cuali ordinal, las barras van por orden alfabético, no por jerarquía real
ggplot(datos) +geom_bar(aes(x =as.character(estado_salud), fill =as.character(estado_salud)),alpha =0.75) + ggthemes::scale_fill_colorblind() +labs(title ="Diagrama de barras de la variable estado salud", x ="Categoría", y ="Frecuencia absoluta",fill ="Categoría") +theme_minimal()
2.1.9 Pregunta 9
Crea el histograma inferior para las variable edad y tiempo de espera.
Code
ggplot(datos) +geom_histogram(aes(x = edad), bins =30, fill ="darkorange", alpha =0.75) +labs(title ="Histograma de edad", subtitle ="Bins = 30",x ="Valores", y ="Frecuencia absoluta") +theme_minimal()
Code
ggplot(datos) +# Define el ancho de las barras y coloresgeom_histogram(aes(x = tiempo_espera), bins =30, fill ="orchid", alpha =0.75) +labs(title ="Histograma de tiempo de espera", subtitle ="Bins = 30",x ="Valores", y ="Frecuencia absoluta") +theme_minimal()
2.1.10 Pregunta 10
Crea el gráfico de densidad inferior para las variable edad y tiempo de espera.
Code
ggplot(datos) +geom_density(aes(x = edad), color ="darkorange", fill ="darkorange", alpha =0.75) +labs(title ="Gráfico de densidad de edad",x ="Valores", y ="Frecuencia relativa") +theme_minimal()
Code
ggplot(datos) +geom_density(aes(x = tiempo_espera), color ="orchid", fill ="orchid", alpha =0.75) +labs(title ="Gráfico de densidad de tiempo de espera",x ="Valores", y ="Frecuencia relativa") +theme_minimal()
2.1.11 Pregunta 11
Realiza un boxplot para edad y un boxplot para numero de visitas PERO por género (dos variables, piensa cómo)
Code
ggplot(datos) +geom_boxplot(aes(y = edad), fill ="lightblue", alpha =0.75) +labs(title ="Boxplot de edad", y ="Edad") +theme_minimal()
Code
ggplot(datos) +geom_boxplot(aes(x = genero, y = tiempo_espera, fill = genero),alpha =0.75) +labs(title ="Boxplot de tiempo de espera por género", x ="Género", y ="Tiempo de Espera") +theme_minimal()
Haciendo uso del gráfico anterior:
¿La variable edad tiene outliers? ¿Qué edad tienen esos pacientes?
¿Quién ha esperado más los hombres o las mujeres?
2.2 🐣 Caso práctico II: bronquitis y tabaco
Vamos a cargar el archivo de datos fumadores.csv donde tenemos datos de 96 pacientes sobre sí o fuman y quienes han desarrollado o no bronquitis.
datos <-read_csv(file ="./datos/fumadores.csv")
Rows: 96 Columns: 3
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (2): fumador, estado
dbl (1): id
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
datos
# A tibble: 96 × 3
id fumador estado
<dbl> <chr> <chr>
1 1 sí bronquitis
2 2 sí bronquitis
3 3 sí bronquitis
4 4 sí bronquitis
5 5 sí bronquitis
6 6 sí bronquitis
7 7 sí bronquitis
8 8 sí bronquitis
9 9 sí bronquitis
10 10 sí bronquitis
# ℹ 86 more rows
2.2.1 Pregunta 1
Realiza la tabla de contigencia de manera absoluta y relativa y responde a las siguientes preguntas
¿Cuántas personas fumaoras tienen bronquitis?
¿Qué % de los fumadores está sano?
¿Qué % del total son a la vez no fumadores y enfermos de bronquitis?
¿Qué % de los enfermos son fumadores?
Code
table(datos$fumador, datos$estado)prop.table(table(datos$fumador, datos$estado))prop.table(table(datos$fumador, datos$estado), margin =1)prop.table(table(datos$fumador, datos$estado), margin =2)# a) 32 personas# b) 38.46%# c) 16%# d) 61.53%
2.2.2 Pregunta 2
Visualiza ambas variables (fumador y estado) a la vez de manera adecuada que nos permita comparar
Code
ggplot(datos) +geom_bar(aes(x = fumador, fill = estado), alpha =0.6, position ="fill") +labs(x ="fumador", y ="Frec relativa", fill ="Estado") +theme_minimal()
2.2.3 Pregunta 3
¿Existen evidencias en la muestra de una asociación entre ambas variables?
Code
datos |>summarise("sig_chisq"=chisq.test(datos$fumador, datos$estado)$p.value,"sig_fisher"=fisher.test(datos$fumador, datos$estado)$p.value)# p-valor < alpha --> hay evidencias para rechazar la hip nula# hay evidencias (no muy fuertes, quizás aumentar tamaño muestral?) de# que las variables son dependientes y existe una asociación
2.2.4 Pregunta 4
Si hubiera asociación, cuantifica la fuerza de dicha asociación (y el sentido) y calcula el riesgo relativo de los fumadores a contraer bronquitis (respecto a no fumadores)
Code
fisher.test(datos$fumador, datos$estado)# OR estimado = 0.3611 ==> piensa que tenemos no fumar primero y luego fumar ==># 1/0.3611 = 2.769316 > 1 ==> hay una asociación positiva entre fumar y tener # bronquitis # La bronquitis en pacientes que fuman es 2.77 veces más frecuente# que en los pacientes que no fuman# RR ratioa <-32# Expuestos con eventob <-16# Expuestos sin eventoc <-20# No expuestos con eventod <-28# No expuestos sin eventoRR <- (a / (a + b)) / (c / (c + d))# El grupo que fuma tiene un riesgo 1.6 veces mayor de que desarrollar bronquitis en comparación con el grupo que no fuma.
2.3 🐣 Caso práctico III: salud mental
Esta la base de datos datos_salud_mental.csv tenemos información recopilada de 100 pacientes que acuden a un centro de salud mental. Se quiere realizar un estudio para ver el impacto que tienen distintas características sobre la ansiedad y depresión en estos 100 pacientes. Los datos incluyen una variedad de variables relacionadas con la salud mental, así como características demográficas y de estilo de vida.
datos <-read_csv(file ="./datos/datos_salud_mental.csv") |> janitor::clean_names()
Rows: 100 Columns: 10
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (3): Genero, UsoDrogasRecreativas, TipoDrogas
dbl (7): ID, Edad, Ansiedad, Depresion, SesionesTerapia, ActividadFisica, Ho...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
ansiedad: nivel de ansiedad del paciente en una escala del 1 al 10.
depresión: nivel de depresión del paciente en una escala del 1 al 10.
sesiones_terapia: número de sesiones de terapia asistidas en el último año.
actividad_fisica: número de días a la semana que el paciente realiza actividad física.
horas_sueno: número de horas promedio de sueño por noche.
uso_drogas_recreativas: indicador de si el paciente ha usado drogas recreativas en el último año.
tipo_drogas: tipo de drogas que ha consumido el paciente.
2.3.1 Pregunta 1
¿De qué tipo es cada variable? Convierte las que consideres a cualis nominales y a cualis ordinales, y si hay alguna variable que deba ser lógica
Code
# id: en realidad esto tendría ser un factor (un texto) ya que no cuenta nada# Cuantitativas: edad, horas_sueno# Cualitativas nominales: genero, tipo_drogas# Cuanitativas discretas: sesiones_terapia y actividad_fisica# Cuantitativas discretas pero que deberíamos tratarlas como cualis ordinales# ya que son escalas: ansiedad, depresión# Binarias (cualis ordinales muy concretas): uso_drogas_recreativasdatos <- datos |>mutate("id"=as.character(id),"genero"=factor(genero), "tipo_drogas"=factor(tipo_drogas),"ansiedad"=factor(ansiedad, levels =as.character(1:10), ordered =TRUE),"depresion"=factor(depresion, levels =as.character(1:10), ordered =TRUE),"uso_drogas_recreativas"= (uso_drogas_recreativas =="Si"))
2.3.2 Pregunta 2
Calcula la tabla de frecuencias absolutas y relativas de género.
Calcula la tabla de contigencia de las variables ansiedad vs genero. Calcula otra para ansiedad vs depresion. Usa useNA = "always" como argumento para incluir los NA
Realiza un gráfico adecuado para la variable edad. Piensa como adaptarlo para tenerlo desagregado por genero.
Code
# Densidadesggplot(datos) +geom_density(aes(x = edad), fill ="#459191", alpha =0.4) +labs(x ="Edad (años)", y ="Densidad (frec relativa)") +theme_minimal()library(ggridges)ggplot(datos) +geom_density_ridges(aes(x = edad, y = genero, fill = genero), alpha =0.4) + ggthemes::scale_fill_colorblind() +labs(x ="Edad (años)", y ="Sexo", fill ="Género") +theme_minimal()# Histograma (mala idea con pocos datos)ggplot(datos) +geom_histogram(aes(x = edad), bins =15, fill ="#459191", alpha =0.4) +labs(x ="Edad (años)", y ="Frec absoluta") +theme_minimal()ggplot(datos) +geom_histogram(aes(x = edad, fill = genero), bins =15, alpha =0.25) +labs(x ="Edad (años)", y ="Frec absoluta") +theme_minimal()# Boxplotggplot(datos) +geom_boxplot(aes(y = edad), fill ="#459191", alpha =0.4,outlier.size =3, outlier.alpha =0.9,outlier.color ="#991293", outlier.shape =18) +labs(y ="Edad") +theme_minimal()ggplot(datos, aes(x = genero, y = edad, fill = genero, color = genero)) +geom_boxplot(alpha =0.4, outlier.size =3, outlier.alpha =0.9,outlier.color ="#991293", outlier.shape =18) + ggthemes::scale_color_colorblind() + ggthemes::scale_fill_colorblind() +guides(color ="none") +labs(x ="Género", y ="Edad", fill ="Género") +theme_minimal()
2.3.6 Pregunta 6
Realiza un gráfico adecuado para visualizar a la vez depresión y ansiedad.
Code
# fíjate que aunque sean números, dado que son variables discretas# de una escala, no permite una correcta visualización un diagrama# de dispersión ya que hay muchos puntos iguales que se solapanggplot(datos) +geom_point(aes(x = depresion, y = ansiedad)) +theme_minimal()# una opción: se ve un patrón (tipo "recta ascedente")ggplot(datos |>count(depresion, ansiedad)) +geom_point(aes(x = depresion, y = ansiedad, color = n, size = n)) +scale_color_viridis_c() +guides(size ="none") +theme_minimal()
2.3.7 Pregunta 7
¿Existe asociación entre genero y uso de drogas? ¿Y entre depresión y ansiedad? Cuantifica la respuesta todo lo que puedas.
Code
resumen_p_valores_1 <- datos |>summarise("sig_chisq"=chisq.test(datos$genero, datos$uso_drogas_recreativas)$p.value,"sig_fisher"=fisher.test(datos$genero, datos$uso_drogas_recreativas)$p.value)
Warning: There was 1 warning in `summarise()`.
ℹ In argument: `sig_chisq = chisq.test(datos$genero,
datos$uso_drogas_recreativas)$p.value`.
Caused by warning in `chisq.test()`:
! Chi-squared approximation may be incorrect
Code
# p-valores >> alpha --> no evidencias para rechazar la independencia --># no hay evidencias para afirmar la dependencia# con tantas categorías Fisher no funcionachisq.test(datos$depresion, datos$ansiedad)
Warning in chisq.test(datos$depresion, datos$ansiedad): Chi-squared
approximation may be incorrect
Pearson's Chi-squared test
data: datos$depresion and datos$ansiedad
X-squared = 174.39, df = 63, p-value = 2.148e-12
Code
# p-valores << alpha --> sí hay evidencias para rechazar la independencia --># sí hay evidencias para afirmar la dependencia