En esta activiad vamos analizar desde el punto de vista estadístico, la relación entre el hábito de fumar y variables cardiometabólicas clave (frecuencia cardíaca y colesterol), así como contrastar proporciones de eventos clínicos (taquicardia y colesterol alto) en una muestra observacional. Para ello, se implementa un flujo de trabajo reproducible en R apoyado en el ecosistema tidyverse para la limpieza, transformación y visualización, y en pruebas de hipótesis clásicas (t de una y dos muestras con corrección de Welch, pruebas de proporciones) complementadas con tamaños de efecto (Cohen’s d y Hedges’ g) que ayudan a interpretar la magnitud práctica de las diferencias más allá del valor p [1], [3].
La estrategia metodológica se estructura en: (i) depuración y estandarización de nombres y tipos de variables; (ii) exploración descriptiva y visual (histogramas, densidades, diagramas de caja y gráficos de barras), (iii) planteamiento formal de hipótesis (H0/H1), selección del contraste (bilateral/unilateral), nivel de significancia y criterios de decisión, y (iv) reporte tabular de resultados con intervalos de confianza e interpretación. Este enfoque sigue lineamientos de análisis de datos reproducibles en R orientados a ciencias de la vida y salud [1] y se fundamenta en los principios de la inferencia estadística clásica (estimación, contrastes, supuestos y potencia) descritos en la literatura estándar [3].
Además, se adopta una visión práctica de la ciencia de datos integrando limpieza, análisis, visualización y comunicación que facilita la trazabilidad y la toma de decisiones sobre evidencia cuantitativa [4]. De manera complementaria, si el estudio requiriera reducir dimensionalidad o construir indicadores compuestos, técnicas como PCA pueden incorporarse para explorar estructuras latentes en los datos, tal como discute la bibliografía especializada reciente [5]. Finalmente, se reconocen desarrollos modernos en analítica y aprendizaje (incluido deep learning) que, aunque no son el foco de este informe, enmarcan el continuo metodológico entre estadística clásica y modelos de mayor complejidad [2].
Configuración del entorno estableciendo la reproducibilidad, cargando de forma automática y silenciosa todos los paquetes necesarios, definiendo un tema gráfico global para ggplot2 y fijando una paleta de colores consistente que se utilizará en todas las visualizaciones posteriores.
knitr::opts_chunk$set(warning = FALSE, message = FALSE)
set.seed(123) # Fija semilla para reproducibilidad (set.seed)
pkgs <- c( # Crea vector con nombres de paquetes (c)
"tidyverse","janitor","broom","rstatix",
"effectsize","knitr","kableExtra","rlang","scales"
) # Lista de paquetes usados en el análisis
need <- setdiff(pkgs, rownames(installed.packages())) # Identifica paquetes faltantes (setdiff + installed.packages + rownames)
if (length(need)) install.packages(need, dependencies=TRUE) # Instala paquetes faltantes con dependencias (install.packages)
invisible(lapply(pkgs, function(p) # Itera sobre paquetes y los carga (lapply)
suppressPackageStartupMessages( # Suprime mensajes de arranque (suppressPackageStartupMessages)
library(p, character.only = TRUE) # Carga paquete por nombre como cadena (library)
)
))
theme_set(ggplot2::theme_minimal(base_size = 12)) # Fija tema gráfico global minimalista con texto base 12 (theme_set + theme_minimal)
# Paleta consistente para todo el informe (vectores de colores hex)
pal_groups <- c("no" = "#1f77b4", "yes" = "#d62728") # Paleta para grupos (no/yes) (vector nombrado)
col_hr_fill <- "#4C78A8" # Color base para HR (constante hex)
col_ch_fill <- "#F58518" # Color base para colesterol (constante hex)
col_mean <- "#2ca02c" # Color para línea de media (constante hex)
col_ref1 <- "#9467bd" # Color para línea de referencia 1 (constante hex)
col_ref2 <- "#e377c2" # Color para línea de referencia 2 (constante hex)
En este bloque cargamos el archivo de datos, procedemos a estandarizar y reparar los nombres de columnas, detectar las variables claves (fumador, frecuencia cardiaca, colesterol y presión arterial), normalizar y transformar estas variables (incluyendo la separación de presión sistólica/diastólica y la creación de indicadores binarios de colesterol alto y taquicardia), eliminar filas duplicadas y generar un reporte tabular del número de valores perdidos por variable, dejando un data frame limpio (df) y un diagnóstico de calidad de datos listo para el análisis estadístico posterior.
data_path <- "smoking_health_data_final.csv" # Define ruta del CSV (asignación de cadena)
raw <- readr::read_csv(data_path, show_col_types = FALSE) # Lee CSV inferiendo tipos sin imprimirlos (readr::read_csv)
raw <- janitor::clean_names(raw) # Estandariza nombres a snake_case, válidos y únicos (janitor::clean_names)
if (any(names(raw) == "")) { # Verifica si hay nombres vacíos (any + names)
idx <- which(names(raw) == "") # Obtiene posiciones de nombres vacíos (which)
names(raw)[idx] <- paste0("unnamed_", idx) # Asigna nombres provisionales únicos (paste0)
} # Cierra condición
utils::str(head(raw, 1)) # Muestra estructura compacta de la primera fila (utils::str + head)
## tibble [1 × 7] (S3: tbl_df/tbl/data.frame)
## $ age : num 54
## $ sex : chr "male"
## $ current_smoker: chr "yes"
## $ heart_rate : num 95
## $ blood_pressure: chr "110/72"
## $ cigs_per_day : num NA
## $ chol : num 219
pick_col <- function(d, candidates) { # Define función auxiliar para elegir primera columna existente (function)
found <- intersect(candidates, names(d)) # Interseca candidatos con nombres del data.frame (intersect + names)
if (length(found) == 0) # Evalúa si no hay coincidencias (length == 0)
stop("No se encontró ninguna columna entre: ", # Lanza error con mensaje descriptivo (stop)
paste(candidates, collapse = ", ")) # Concatena candidatos en cadena (paste)
found[1] # Devuelve la primera coincidencia (indexación)
} # Cierra función
col_smoker <- ifelse("current_smoker" %in% names(raw), # Usa nombre canónico si existe (ifelse + %in%)
"current_smoker",
pick_col(raw, c("smoker","is_smoker","fumador"))) # O el primero que exista (pick_col)
col_hr <- pick_col(raw, c("heart_rate","hr","frecuencia_cardiaca")) # Detecta nombre real de HR (pick_col)
col_chol <- pick_col(raw, c("chol","cholesterol","colesterol")) # Detecta nombre real de colesterol (pick_col)
col_bp <- if ("blood_pressure" %in% names(raw)) "blood_pressure" else NA_character_ # Detecta presión arterial si existe (%in%)
df <- raw |> # Inicia tubería con datos crudos (|>)
dplyr::mutate( # Modifica/crea variables (dplyr::mutate)
!!col_smoker := dplyr::case_when( # Normaliza fumador a yes/no (case_when con tidy-eval !!)
tolower(.data[[col_smoker]]) %in% # Convierte a minúsculas y compara conjunto (tolower + %in%)
c("yes","y","1","si","sí","true") ~ "yes", # Mapea valores afirmativos a "yes" (vector literal)
tolower(.data[[col_smoker]]) %in% # Compara valores negativos (tolower + %in%)
c("no","n","0","false") ~ "no", # Mapea a "no" (asignación de cadena)
TRUE ~ as.character(.data[[col_smoker]]) # Mantiene valor original como carácter (as.character)
), # Cierra case_when
!!col_smoker := factor(.data[[col_smoker]], # Convierte a factor ordenado no/yes (factor)
levels = c("no","yes")) # Define orden de niveles (levels)
) # Cierra mutate
if (!is.na(col_bp) && col_bp %in% names(df)) { # Si existe columna de presión arterial (is.na + %in%)
if ("separate_wider_delim" %in% getNamespaceExports("tidyr")) { # Usa API nueva si está disponible (getNamespaceExports)
df <- tidyr::separate_wider_delim( # Separa texto "120/80" en dos columnas (separate_wider_delim)
df, # Data.frame de entrada (df)
cols = !!rlang::sym(col_bp), # Selecciona columna por nombre con símbolo (rlang::sym)
delim = "/", # Define delimitador de separación (delim)
names = c("sbp","dbp"), # Nombres de salida para sistólica/diastólica (names)
too_few = "align_start" # Alinea si faltan valores (too_few)
) # Cierra llamada
df <- dplyr::mutate(df, # Convierte a numéricos las nuevas columnas (mutate)
dplyr::across(c(sbp, dbp), readr::parse_number)) # Aplica parseo numérico sobre columnas (across + parse_number)
} else { # Rama alternativa si API nueva no existe (else)
df <- tidyr::separate( # Separa texto usando API clásica (tidyr::separate)
df, !!rlang::sym(col_bp), # Data y columna a separar (rlang::sym)
into = c("sbp","dbp"), # Nombres de columnas resultantes (into)
sep = "/", # Delimitador de separación (sep)
convert = TRUE, # Convierte tipos cuando es posible (convert)
remove = TRUE, # Remueve la columna original (remove)
extra = "merge", # Une excedentes si sobran separadores (extra)
fill = "right" # Rellena a la derecha si faltan valores (fill)
) # Cierra llamada
} # Cierra condición anidada
} # Cierra condición principal
df <- df |> # Continúa tubería sobre df (|>)
dplyr::mutate( # Crea indicadores binarios (mutate)
chol_high = ifelse(!is.na(.data[[col_chol]]) & # 1 si colesterol > 240 y no es NA (ifelse + !is.na)
.data[[col_chol]] > 240, 1L, 0L),
tachycardia = ifelse(!is.na(.data[[col_hr]]) & # 1 si HR > 100 y no es NA (ifelse + !is.na)
.data[[col_hr]] > 100, 1L, 0L)
) |>
dplyr::distinct() # Elimina filas duplicadas exactas (distinct)
na_report <- sapply(df, function(x) sum(is.na(x))) # Cuenta NAs por columna (sapply + is.na + sum)
na_tbl <- tibble::tibble( # Crea tabla con nombres y conteo de NAs (tibble::tibble)
variable = names(na_report), # Columna de nombres de variables (names)
na = as.integer(na_report) # Columna de conteo como entero (as.integer)
) |>
dplyr::arrange(dplyr::desc(na)) # Ordena de mayor a menor número de NAs (arrange + desc)
knitr::kable(na_tbl, # Renderiza tabla en el reporte (knitr::kable)
caption = "Conteo de valores perdidos por variable", # Título de la tabla (caption)
digits = 0 # Formato de decimales (digits)
) |>
kableExtra::kable_styling(full_width = FALSE) # Aplica estilo sin ancho completo (kable_styling)
| variable | na |
|---|---|
| cigs_per_day | 14 |
| chol | 7 |
| age | 0 |
| sex | 0 |
| current_smoker | 0 |
| heart_rate | 0 |
| sbp | 0 |
| dbp | 0 |
| chol_high | 0 |
| tachycardia | 0 |
Calidad general de los datos
La mayoría de variables claves para el análisis (edad, sexo, condición de fumador, frecuencia cardiaca, presión sistólica/diastólica y los indicadores binarios chol_high y tachycardia) no presentan valores perdidos, lo cual es muy favorable para los contrastes de medias y proporciones.
Variables con problemas de completitud
cigs_per_day (intensidad del hábito de fumar) es la variable con mayor cantidad de datos faltantes (14 casos).
Esto implica que cualquier análisis que use “cigarrillos por día” tendrá una muestra efectiva menor y podría estar sesgado si los NAs no son aleatorios (por ejemplo, si quienes no responden son justamente los que más fuman).
chol tiene 7 valores perdidos.
Aunque el indicador derivado chol_high no tiene NAs (porque se codificó 0 cuando el valor es NA o ≤240), conviene tener presente que el análisis que use el colesterol como variable continua perderá esos 7 registros.
En este bloque se realizar la exploración descriptiva inicial de la muestra, obteniendo un resumen numérico global (tamaño muestral, medias, desviaciones estándar y proporciones de colesterol alto y taquicardia) y generando visualizaciones univariadas y por grupos (histogramas, densidades y boxplots de frecuencia cardíaca y colesterol según condición de fumador, además de un gráfico de barras con las proporciones de colesterol alto y taquicardia frente a valores de referencia), para caracterizar la distribución y magnitud de las variables clave antes de aplicar las pruebas de hipótesis.
desc_tbl <- df |> # Inicia resumen descriptivo (|>)
dplyr::summarise( # Calcula estadísticas agregadas (summarise)
n = dplyr::n(), # Tamaño muestral (n)
mean_hr = mean(.data[[col_hr]], na.rm = TRUE), # Media de HR ignorando NA (mean)
sd_hr = sd( .data[[col_hr]], na.rm = TRUE), # Desviación estándar de HR (sd)
mean_ch = mean(.data[[col_chol]], na.rm = TRUE), # Media de colesterol (mean)
sd_ch = sd( .data[[col_chol]], na.rm = TRUE), # Desviación estándar de colesterol (sd)
prop_chh = mean(chol_high, na.rm = TRUE), # Proporción colesterol alto (mean sobre 0/1)
prop_tach = mean(tachycardia, na.rm = TRUE) # Proporción taquicardia (mean sobre 0/1)
) # Cierra summarise
knitr::kable(desc_tbl, digits = 3, # Muestra tabla con 3 decimales (kable)
caption = "Resumen descriptivo") |>
kableExtra::kable_styling(full_width = FALSE) # Estiliza tabla sin ancho completo (kable_styling)
| n | mean_hr | sd_hr | mean_ch | sd_ch | prop_chh | prop_tach |
|---|---|---|---|---|---|---|
| 3900 | 75.689 | 12.015 | 236.596 | 44.375 | 0.428 | 0.024 |
g_hr_hist <- ggplot2::ggplot(df, # Crea objeto ggplot para HR (ggplot)
ggplot2::aes(x = .data[[col_hr]])) +
ggplot2::geom_histogram(bins = 30, color = "white", fill = col_hr_fill) + # Hist a color (geom_histogram + fill)
ggplot2::geom_vline(xintercept = mean(df[[col_hr]], na.rm = TRUE),
linetype = "dashed", color = col_mean) + # Línea media en color (geom_vline)
ggplot2::geom_vline(xintercept = 75, linetype = "dotted", color = col_ref1) + # Línea ref 75 en color (geom_vline)
ggplot2::labs(title = "Histograma de frecuencia cardiaca", x = "lpm", y = "Frecuencia") # Títulos (labs)
g_hr_dens <- ggplot2::ggplot(df, # Gráfico de densidad para HR (ggplot)
ggplot2::aes(x = .data[[col_hr]])) +
ggplot2::geom_density(alpha = 0.5, fill = col_hr_fill) + # Densidad rellena a color (geom_density + fill)
ggplot2::geom_vline(xintercept = mean(df[[col_hr]], na.rm = TRUE),
linetype = "dashed", color = col_mean) + # Línea media (geom_vline)
ggplot2::geom_vline(xintercept = 75, linetype = "dotted", color = col_ref1) + # Línea ref 75 (geom_vline)
ggplot2::labs(title = "Densidad de frecuencia cardiaca", x = "lpm", y = "Densidad") # Etiquetas (labs)
g_hr_box <- ggplot2::ggplot(df, # Boxplot de HR por fumador (ggplot)
ggplot2::aes(x = .data[[col_smoker]], y = .data[[col_hr]], fill = .data[[col_smoker]])) +
ggplot2::geom_boxplot(alpha = 0.8) + # Cajas rellenas por grupo (geom_boxplot + fill)
ggplot2::scale_fill_manual(values = pal_groups) + # Paleta para grupos (scale_fill_manual)
ggplot2::geom_hline(yintercept = mean(df[[col_hr]], na.rm = TRUE),
linetype = "dashed", color = col_mean) + # Línea media global (geom_hline)
ggplot2::labs(title = "Frecuencia cardiaca por fumador", x = "Fumador", y = "lpm", fill = "Fumador") # Etiquetas (labs)
g_ch_hist <- ggplot2::ggplot(df, # Histograma de colesterol (ggplot)
ggplot2::aes(x = .data[[col_chol]])) +
ggplot2::geom_histogram(bins = 30, color = "white", fill = col_ch_fill) + # Hist a color (geom_histogram + fill)
ggplot2::geom_vline(xintercept = mean(df[[col_chol]], na.rm = TRUE),
linetype = "dashed", color = col_mean) + # Línea media (geom_vline)
ggplot2::geom_vline(xintercept = 200, linetype = "dotted", color = col_ref1) + # Umbral 200 (geom_vline)
ggplot2::geom_vline(xintercept = 240, linetype = "dotted", color = col_ref2) + # Umbral 240 (geom_vline)
ggplot2::labs(title = "Histograma de colesterol (mg/dL)", x = "mg/dL", y = "Frecuencia") # Etiquetas (labs)
g_ch_dens <- ggplot2::ggplot(df, # Densidad de colesterol (ggplot)
ggplot2::aes(x = .data[[col_chol]])) +
ggplot2::geom_density(alpha = 0.5, fill = col_ch_fill) + # Densidad rellena a color (geom_density + fill)
ggplot2::geom_vline(xintercept = mean(df[[col_chol]], na.rm = TRUE),
linetype = "dashed", color = col_mean) + # Línea media (geom_vline)
ggplot2::geom_vline(xintercept = 200, linetype = "dotted", color = col_ref1) + # Umbral 200 (geom_vline)
ggplot2::geom_vline(xintercept = 240, linetype = "dotted", color = col_ref2) + # Umbral 240 (geom_vline)
ggplot2::labs(title = "Densidad de colesterol", x = "mg/dL", y = "Densidad") # Etiquetas (labs)
g_ch_box <- ggplot2::ggplot(df, # Boxplot de colesterol por fumador (ggplot)
ggplot2::aes(x = .data[[col_smoker]], y = .data[[col_chol]], fill = .data[[col_smoker]])) +
ggplot2::geom_boxplot(alpha = 0.8) + # Cajas rellenas por grupo (geom_boxplot + fill)
ggplot2::scale_fill_manual(values = pal_groups) + # Paleta para grupos (scale_fill_manual)
ggplot2::geom_hline(yintercept = mean(df[[col_chol]], na.rm = TRUE),
linetype = "dashed", color = col_mean) + # Línea media (geom_hline)
ggplot2::labs(title = "Colesterol por fumador", x = "Fumador", y = "mg/dL", fill = "Fumador") # Etiquetas (labs)
prop_tbl <- df |> # Prepara tabla de proporciones (|>)
dplyr::summarise( # Calcula proporciones globales (summarise)
chol_high = mean(chol_high, na.rm = TRUE), # Proporción colesterol alto (mean)
tachycardia = mean(tachycardia, na.rm = TRUE) # Proporción taquicardia (mean)
) |>
tidyr::pivot_longer(everything(), # Pivotea a formato largo (pivot_longer)
names_to = "indicador", # Nombre de variable de indicadores (names_to)
values_to = "prop") # Nombre de columna de proporciones (values_to)
g_props <- ggplot2::ggplot(prop_tbl, # Barras de proporciones (ggplot)
ggplot2::aes(x = indicador, y = prop, fill = indicador)) +
ggplot2::geom_col(alpha = 0.9) + # Barras rellenas a color (geom_col + alpha)
ggplot2::scale_fill_manual(values = c("chol_high" = "#17becf", "tachycardia" = "#bcbd22")) + # Colores por indicador (scale_fill_manual)
ggplot2::geom_hline(yintercept = 0.20, linetype = "dotted", color = col_ref1) + # Línea referencia 20% (geom_hline)
ggplot2::geom_hline(yintercept = 0.05, linetype = "dashed", color = col_ref2) + # Línea referencia 5% (geom_hline)
ggplot2::scale_y_continuous(labels = scales::percent_format(accuracy = 1)) + # Formatea eje Y en % (percent_format)
ggplot2::labs(title = "Proporciones observadas vs referencias", x = NULL, y = "Proporcion", fill = "Indicador") # Etiquetas (labs)
print(g_hr_hist); print(g_hr_dens); print(g_hr_box) # Imprime gráficos de HR (print)
print(g_ch_hist); print(g_ch_dens); print(g_ch_box) # Imprime gráficos de colesterol (print)
print(g_props) # Imprime gráfico de proporciones (print)
Tamaño muestral (n): 3900 sujetos. Es una muestra grande, lo que da buena potencia para los análisis estadísticos posteriores.
Frecuencia cardíaca (mean_hr = 75.689, sd_hr = 12.015):La frecuencia cardíaca promedio es de ~75.7 lpm, con una desviación estándar de ~12 lpm.
Esto indica que, en general, la muestra presenta una frecuencia cardíaca de reposo algo elevada pero todavía dentro de rangos habituales, con variabilidad moderada entre individuos.
Colesterol (mean_ch = 236.596, sd_ch = 44.375):
El colesterol medio es de ~236.6 mg/dL, valor cercano al umbral de 240 mg/dL usado para definir colesterol alto.
Proporción de colesterol alto (prop_chh = 0.428):
Aproximadamente el 42.8 % de los sujetos presenta colesterol alto según el punto de corte definido.
Esto confirma una prevalencia elevada de hipercolesterolemia en la población estudiada.
Proporción de taquicardia (prop_tach = 0.024):
Solo alrededor del 2.4 % de los individuos cumple el criterio de taquicardia.
En comparación con el colesterol alto, la taquicardia es un evento mucho menos frecuente.
En conclusión, en esta muestra de 3900 personas, la frecuencia cardíaca presenta valores medios moderadamente elevados pero con baja prevalencia de taquicardia, mientras que los niveles de colesterol muestran una media cercana al umbral clínico y una proporción muy alta de sujetos con colesterol elevado, lo que posiciona a la dislipidemia como el principal factor de riesgo observado en las variables analizadas.
El histograma de la frecuencia cardíaca muestra una distribución aproximadamente unimodal, con la mayor concentración de observaciones entre 65 y 85 latidos por minuto (lpm). La línea vertical discontinua indica la media muestral, cercana a 75 lpm, lo que sugiere que, en promedio, los sujetos presentan una frecuencia cardiaca de reposo moderadamente elevada pero dentro de rangos habituales. Se aprecia una cola hacia la derecha con pocos casos por encima de 100–110 lpm, lo que indica la presencia de algunos valores altos (posibles taquicardias), aunque representan una fracción pequeña de la muestra.
La curva de densidad suavizada confirma lo observado en el histograma: la distribución es casi simétrica alrededor de la media, con un pico bien definido próximo a 75 lpm. La cola derecha es ligeramente más prolongada, lo que refleja una leve asimetría positiva debida a sujetos con frecuencias cardíacas más altas. En conjunto, estos resultados indican que la media y la desviación estándar son medidas razonables para describir la variabilidad de la frecuencia cardíaca en la muestra.
El diagrama de cajas compara la frecuencia cardíaca entre no fumadores y fumadores. Visualmente, la mediana del grupo de fumadores es ligeramente superior a la de los no fumadores, lo que sugiere que los fumadores presentan, en promedio, una frecuencia cardíaca algo más elevada. No obstante, existe un amplio solapamiento entre ambos grupos y una variabilidad considerable, con presencia de valores atípicos altos en los dos casos. La línea discontinua verde, que representa la media global, se sitúa entre ambas cajas, indicando que cualquier diferencia entre grupos deberá ser confirmada mediante las pruebas de hipótesis posteriores.
El histograma del colesterol total (mg/dL) muestra una distribución unimodal con mayor concentración de observaciones entre aproximadamente 190 y 260 mg/dL. La línea discontinua verde marca la media muestral, situada en torno a 230–240 mg/dL, mientras que las líneas verticales punteadas señalan los puntos de corte clínicos de 200 y 240 mg/dL. Se observa que una proporción importante de los sujetos presenta valores por encima de 200 mg/dL y que una fracción no despreciable supera los 240 mg/dL, lo que evidencia una carga relevante de hipercolesterolemia en la población analizada.
La gráfica de densidad corrobora que la distribución del colesterol es aproximadamente normal con una ligera asimetría hacia la derecha. El máximo de densidad se sitúa algo por debajo de la media, mientras que la cola derecha se prolonga hacia valores elevados. La ubicación de los umbrales de 200 y 240 mg/dL respecto a la masa de la distribución permite visualizar que una parte considerable de la muestra se encuentra en rangos limítrofes o francamente altos de colesterol.
En el boxplot que compara los niveles de colesterol entre no fumadores y fumadores, las medianas de ambos grupos aparecen muy próximas, y las cajas presentan amplitudes similares. Esto sugiere que, de forma exploratoria, el hábito de fumar no se asocia con diferencias marcadas en el colesterol total. En ambos grupos se observan varios valores atípicos altos, lo que indica una gran variabilidad intra-grupo. Nuevamente, cualquier diferencia sutil entre fumadores y no fumadores deberá evaluarse formalmente mediante los contrastes de hipótesis.
El gráfico de barras resume las proporciones de sujetos con colesterol alto (chol_high) y con taquicardia (tachycardia), comparándolas con valores de referencia del 20 % y 5 %, respectivamente. Aproximadamente el 40-45 % de la muestra presenta colesterol alto, porcentaje claramente superior a la referencia del 20 %, lo que refuerza la idea de una elevada prevalencia de dislipidemia en esta población. En contraste, la proporción de taquicardia se sitúa alrededor del 2-3 %, por debajo de la referencia del 5 %, indicando que las frecuencias cardíacas francamente elevadas son relativamente poco frecuentes. En conjunto, estos resultados destacan al colesterol elevado como el principal problema cardiovascular en el conjunto de variables analizadas.
En este bloque vamos contrastar estadísticamente si la media poblacional de la frecuencia cardíaca (μ_HR) difiere de 75 lpm, aplicando una prueba t de una muestra bilateral con α = 0,05, calcular el tamaño de efecto (d de Cohen) frente al valor de referencia 75, presentar los resultados en una tabla formateada y emitir automáticamente la decisión sobre H₀ (“rechazar” o “no rechazar”) junto con el p-valor correspondiente.
Hipótesis
- H0: μ_HR = 75 (lpm)
- H1: μ_HR ≠ 75 (lpm)
Parámetro: μ_HR (media poblacional de frecuencia
cardíaca).
Prueba: t de una muestra (bilateral).
Nivel de significancia: α = 0.05.
Criterio: si p < α ⇒ rechazar
H0; en otro caso ⇒ no rechazar H0.
alpha <- 0.05 # Define nivel de significancia (asignación)
ht_hr <- t.test(df[[col_hr]], mu = 75, # Ejecuta t(1 muestra) vs 75 (t.test)
alternative = "two.sided")
d_hr <- effectsize::cohens_d(df[[col_hr]], mu = 75, # Calcula d de Cohen vs 75 (cohens_d)
within = FALSE)
broom::tidy(ht_hr) |> # Convierte salida a tibble (broom::tidy)
dplyr::mutate(cohens_d = d_hr$Cohens_d) |> # Añade tamaño de efecto d (mutate)
knitr::kable(digits = 4, # Formatea tabla de resultados (kable)
caption = "t (1 muestra): HR vs 75 (bilateral)") |>
kableExtra::kable_styling(full_width = FALSE) # Estilo de tabla (kable_styling)
| estimate | statistic | p.value | parameter | conf.low | conf.high | method | alternative | cohens_d |
|---|---|---|---|---|---|---|---|---|
| 75.689 | 3.5809 | 3e-04 | 3899 | 75.3118 | 76.0662 | One Sample t-test | two.sided | 0.0573 |
dec_hr <- ifelse(ht_hr$p.value < alpha, "Rechazar H0", "No rechazar H0") # Regla de decisión (ifelse)
paste("Decisión (α = 0.05):", dec_hr, "| p-valor =", signif(ht_hr$p.value, 4)) # Mensaje de decisión (paste + signif)
## [1] "Decisión (α = 0.05): Rechazar H0 | p-valor = 0.0003465"
El resultado de la prueba t de una muestra para la frecuencia cardíaca se resume así:
En consecuencia, se rechaza H₀ y se concluye que, estadísticamente, la media poblacional de frecuencia cardíaca es distinta de 75 lpm. Sin embargo, la diferencia estimada es de apenas ≈ 0.69 lpm por encima de 75, con un tamaño de efecto prácticamente nulo. Esto indica que, aunque la diferencia es significativa desde el punto de vista estadístico (por el gran tamaño de la muestra), no parece tener relevancia clínica o práctica.
En este paso vamos a evaluar si la media poblacional de colesterol es significativamente mayor que 200 mg/dL, aplicando una prueba t de una muestra unilateral derecha con α = 0,05, calcular el tamaño de efecto (d de Cohen) respecto a ese umbral clínico, presentar los resultados en una tabla formateada y generar automáticamente la decisión sobre H₀ (“rechazar” o “no rechazar”) junto con el p-valor correspondiente.
Hipótesis
- H0: μ_col ≤ 200 (mg/dL)
- H1: μ_col > 200 (mg/dL)
Parámetro: μ_col (media poblacional de
colesterol).
Prueba: t de una muestra (unilateral derecha).
Nivel de significancia: α = 0.05.
Criterio: si p < α ⇒ rechazar
H0.
alpha <- 0.05 # Nivel de significancia (asignación)
ht_ch <- t.test(df[[col_chol]], mu = 200, # t(1 muestra) vs 200 unilateral derecha (t.test)
alternative = "greater")
d_ch <- effectsize::cohens_d(df[[col_chol]], mu = 200, # d de Cohen vs 200 (cohens_d)
within = FALSE)
broom::tidy(ht_ch) |> # broom::tidy() convierte el objeto de la prueba t (ht_ch),
# resultado de t.test(), en un tibble ordenado con columnas como
# estimate, statistic, p.value, conf.low, conf.high, etc.
dplyr::mutate(cohens_d = d_ch$Cohens_d) |> # dplyr::mutate() agrega una nueva columna llamada 'cohens_d'
# al tibble; le asigna el valor del tamaño de efecto d de Cohen
# extraído del objeto d_ch (d_ch$Cohens_d).
knitr::kable( # knitr::kable() transforma ese tibble enriquecido en una tabla
# formateada lista para incluir en el informe (HTML, PDF, Word).
digits = 4, # digits = 4 indica que los valores numéricos se muestran
# con 4 cifras decimales.
caption = "t (1 muestra): Colesterol > 200 (unilateral)"
# caption define el título o leyenda que aparecerá encima
# de la tabla en el documento.
) |>
kableExtra::kable_styling(full_width = FALSE)
| estimate | statistic | p.value | parameter | conf.low | conf.high | method | alternative | cohens_d |
|---|---|---|---|---|---|---|---|---|
| 236.5959 | 51.4557 | 0 | 3892 | 235.4258 | Inf | One Sample t-test | greater | 0.8247 |
# kableExtra::kable_styling() aplica estilos adicionales a la tabla.
# full_width = FALSE evita que la tabla ocupe todo el ancho de la página,
# mejorando la presentación y la legibilidad.
dec_ch <- ifelse(ht_ch$p.value < alpha, "Rechazar H0", "No rechazar H0") # Regla de decisión (ifelse)
paste("Decisión (α = 0.05):", dec_ch, "| p-valor =", signif(ht_ch$p.value, 4)) # Mensaje (paste + signif)
## [1] "Decisión (α = 0.05): Rechazar H0 | p-valor = 0"
El resultado de la prueba t de una muestra para colesterol (H₀: μ_col ≤ 200; H₁: μ_col > 200) se interpreta así:
Media muestral (estimate): xˉ=236.60 mg/dL, es decir, en promedio los sujetos están 36.6 mg/dL por encima del valor de referencia de 200 mg/dL.
Estadístico t (statistic = 51.4557, gl = 3892): Es un valor extremadamente alto; indica que la diferencia entre la media observada y 200 mg/dL son muchas desviaciones estándar por encima del valor nulo.
p-valor ≈ 0: R redondea el p-valor a 0 (en realidad es “menor que la precisión numérica de la máquina”). Al ser un test unilateral derecha, esto implica evidencia abrumadora contra H₀. Con α = 0.05, la regla de decisión “Rechazar H0” está completamente justificada.
IC 95 % unilateral: [235.43;+∞) mg/dL. Incluso en el límite inferior del intervalo de confianza, la media poblacional se sitúa muy por encima de 200 mg/dL, por lo que no es plausible que la media real sea ≤ 200.
Tamaño de efecto (cohens_d = 0.8247): Un d ≈ 0.82 se considera un efecto grande, es decir, la diferencia entre la media observada y el umbral de 200 mg/dL no solo es estadísticamente significativa sino también relevante en términos prácticos o clínicos.
En conclusión y con base en esta prueba t unilateral, se rechaza H₀ y se concluye que la media poblacional de colesterol en la muestra es significativamente mayor que 200 mg/dL, con una diferencia amplia y clínicamente importante, lo que confirma una situación de riesgo elevado por hipercolesterolemia en la población analizada.
En este bloque se evalua si la proporción poblacional de personas con colesterol alto (> 240 mg/dL) es significativamente mayor al 20 %, mediante una prueba de proporciones (prop.test) unilateral derecha con corrección de continuidad y α = 0,05, calculando la proporción observada, contrastándola con el valor teórico del 20 %, presentando los resultados en una tabla formateada y generando automáticamente la decisión sobre H₀ (“rechazar” o “no rechazar”) junto con el p-valor correspondiente.
Hipótesis
- H0: p = 0.20
- H1: p > 0.20
Parámetro: p (proporción poblacional con colesterol
> 240 mg/dL).
Prueba: prop.test (corrección de continuidad).
Nivel de significancia: α = 0.05.
Criterio: si p < α ⇒ rechazar
H0.
alpha <- 0.05 # Nivel de significancia (asignación)
x_ch <- sum(df$chol_high == 1, na.rm = TRUE) # Éxitos: col alto (sum)
n_ch <- sum(!is.na(df$chol_high)) # Total: no NA (sum)
pt_ch <- prop.test(x = x_ch, n = n_ch, p = 0.20, # Prueba de proporción unilateral (prop.test)
alternative = "greater", correct = TRUE)
broom::tidy(pt_ch) |> # broom::tidy() convierte el objeto de la prueba de proporciones
# (pt_ch, resultado de prop.test) en un tibble ordenado con
# columnas como estimate, statistic, p.value, conf.low, conf.high, etc.
knitr::kable( # knitr::kable() toma ese tibble y lo transforma en una tabla
# formateada para el informe (HTML, PDF o Word).
digits = 4, # digits = 4 indica que los valores numéricos se mostrarán
# con 4 cifras decimales.
caption = "Proporcion col alto vs 20 por ciento (unilateral)"
# caption define el título o leyenda de la tabla que aparecerá
# en el documento.
) |>
kableExtra::kable_styling(full_width = FALSE)
| estimate | statistic | p.value | parameter | conf.low | conf.high | method | alternative |
|---|---|---|---|---|---|---|---|
| 0.4279 | 1265.116 | 0 | 1 | 0.4148 | 1 | 1-sample proportions test with continuity correction | greater |
# kableExtra::kable_styling() aplica estilos adicionales a la tabla.
# full_width = FALSE evita que la tabla ocupe todo el ancho de la página,
# mejorando la presentación y la legibilidad.
dec_p_ch <- ifelse(pt_ch$p.value < alpha, "Rechazar H0", "No rechazar H0") # Decisión (ifelse)
paste("Decisión (α = 0.05):", dec_p_ch, "| p-valor =", signif(pt_ch$p.value, 4)) # Mensaje (paste)
## [1] "Decisión (α = 0.05): Rechazar H0 | p-valor = 2.153e-277"
Hipótesis
Del resumen descriptivo previo sabemos que la proporción observada de colesterol alto (chol_high) es aproximadamente 0.428, es decir, cerca del 42.8 % de la muestra presenta colesterol > 240 mg/dL.
El mensaje del test indica:
Decisión (α = 0.05): Rechazar H0 | p-valor = 2.153e-277
Esto significa que el p-valor es extremadamente pequeño (2.153×10−2772.153 ^{-277}2.153×10−277), prácticamente cero, muy por debajo del nivel de significancia α=0.05= 0.05α=0.05.
Conclusiones
Con un p-valor tan reducido, existe evidencia abrumadora para rechazar H₀.
Se concluye que la proporción poblacional de personas con colesterol > 240 mg/dL es significativamente mayor al 20 %.
La proporción observada (~42.8 %) casi duplica el valor de referencia del 20 %, con una diferencia de alrededor de 23 puntos porcentuales.
No solo la diferencia es estadísticamente significativa, sino que además es grande y clínicamente relevante, indicando una alta prevalencia de hipercolesterolemia en la población analizada.
En este paso vamos aevaluar si la proporción poblacional de personas con taquicardia (HR > 100 lpm) es distinta del 5 %, mediante una prueba de proporciones bilateral (prop.test) con α = 0,05, calculando la proporción observada a partir de la variable tachycardia, comparándola con el valor teórico de 0,05, presentando los resultados en una tabla formateada y generando automáticamente la decisión sobre H₀ (“rechazar” o “no rechazar”) junto con el p-valor correspondiente.
Hipótesis
- H0: p = 0.05
- H1: p ≠ 0.05
Parámetro: p (proporción poblacional con HR > 100
lpm).
Prueba: prop.test (bilateral).
Nivel de significancia: α = 0.05.
Criterio: si p < α ⇒ rechazar
H0.
alpha <- 0.05 # Nivel de significancia (asignación)
x_ta <- sum(df$tachycardia == 1, na.rm = TRUE) # Éxitos: taquicardia (sum)
n_ta <- sum(!is.na(df$tachycardia)) # Total: no NA (sum)
pt_ta <- prop.test(x = x_ta, n = n_ta, p = 0.05, # Prueba de proporción bilateral (prop.test)
alternative = "two.sided", correct = TRUE)
broom::tidy(pt_ta) |> # broom::tidy() convierte el objeto de la prueba de proporciones
# (pt_ta, resultado de prop.test) en un tibble ordenado con
# columnas como estimate, statistic, p.value, conf.low, conf.high, etc.
knitr::kable( # knitr::kable() toma ese tibble y lo transforma en una tabla
# formateada para el informe (HTML, PDF, Word).
digits = 4, # digits = 4 indica que los valores numéricos se mostrarán
# con 4 decimales.
caption = "Proporción taquicardia = 5% (bilateral)"
# caption define el título o leyenda de la tabla que aparecerá
# en el documento.
) |>
kableExtra::kable_styling(full_width = FALSE)
| estimate | statistic | p.value | parameter | conf.low | conf.high | method | alternative |
|---|---|---|---|---|---|---|---|
| 0.0238 | 55.6127 | 0 | 1 | 0.0194 | 0.0293 | 1-sample proportions test with continuity correction | two.sided |
# kableExtra::kable_styling() aplica estilos adicionales a la tabla.
# full_width = FALSE hace que la tabla no ocupe todo el ancho
# de la página, mejorando la presentación y la legibilidad.
dec_p_ta <- ifelse(pt_ta$p.value < alpha, "Rechazar H0", "No rechazar H0") # Decisión (ifelse)
paste("Decisión (α = 0.05):", dec_p_ta, "| p-valor =", signif(pt_ta$p.value, 4)) # Mensaje (paste)
## [1] "Decisión (α = 0.05): Rechazar H0 | p-valor = 8.825e-14"
Proporción observada (estimate): p^=0.0238≈2.38% Es decir, en la muestra solo ~2.4 % de las personas presenta taquicardia.
Intervalo de confianza 95 %: [0.0194; 0.0293], es decir, entre 1.94 % y 2.93 %. Todo el intervalo queda por debajo del 5 %, lo que ya indica que el 5 % no es un valor plausible para la proporción poblacional.
Estadístico de prueba: statistic = 55.6127 (chi-cuadrado con 1 g.l.), muy grande en valor absoluto, lo que refleja una discrepancia importante entre la proporción observada (2.4 %) y la teórica (5 %).
p-valor ≈ 8.825 × 10⁻¹⁴ Es muchísimo menor que α = 0.05, por lo que la regla automática “Rechazar H₀” es correcta.
Conclusiones
Con un p-valor tan pequeño y un IC que no contiene el 5 %, hay evidencia estadísticamente muy fuerte para rechazar H₀. Se concluye que la proporción de personas con taquicardia en la población no es del 5 %, sino significativamente distinta.
Dado que la proporción observada (~2.4 %) es claramente menor que el 5 %, la evidencia apunta a que la taquicardia es menos frecuente de lo que planteaba la hipótesis nula.
En términos prácticos:
En este paso vamos comparar los niveles de colesterol entre fumadores y no fumadores para determinar si existe una diferencia estadísticamente significativa entre sus medias poblacionales. Para ello, prepara los datos, aplica una prueba t de dos muestras de Welch (bilateral) con α = 0,05, calcula el tamaño de efecto Hedges’ g con su intervalo de confianza, presenta los resultados en una tabla formateada y genera automáticamente la decisión sobre la hipótesis nula (rechazar o no rechazar H₀) junto con el p-valor correspondiente.
Hipótesis
- H0: μ_col,fum = μ_col,no
- H1: μ_col,fum ≠ μ_col,no
Parámetro: diferencia de medias poblacionales de
colesterol por condición de fumador.
Prueba: t de dos muestras (Welch, varianzas no asumidas
iguales).
Nivel de significancia: α = 0.05.
Tamaño de efecto: Hedges’ g (grupos
independientes).
Criterio: si p < α ⇒ rechazar
H0.
alpha <- 0.05 # Nivel de significancia (asignación)
aux_ch <- df |> # Prepara datos para t-test (|>)
dplyr::select(grupo = .data[[col_smoker]], # Selecciona grupo fumador (select + renombrado)
chol = .data[[col_chol]]) |>
dplyr::filter(!is.na(grupo) & !is.na(chol)) # Elimina NAs de análisis (filter)
ht_ch_sm <- t.test(chol ~ grupo, data = aux_ch, # t de 2 muestras Welch (t.test fórmula)
alternative = "two.sided")
g_ch_sm <- effectsize::hedges_g(chol ~ grupo, data = aux_ch) # Tamaño de efecto Hedges g (hedges_g)
broom::tidy(ht_ch_sm) |> # broom::tidy() convierte el objeto de la prueba t (ht_ch_sm)
# en un data frame/tibble ordenado con columnas como:
# estimate, statistic, p.value, conf.low, conf.high, etc.
dplyr::bind_cols( # dplyr::bind_cols() une por columnas (en paralelo)
# el tibble anterior con otro tibble (el de Hedges' g),
# creando una sola tabla con resultados de la prueba y del tamaño de efecto.
g_ch_sm |> # g_ch_sm es el objeto con el resultado de Hedges' g
# calculado por effectsize::hedges_g() para el colesterol.
dplyr::select( # dplyr::select() selecciona y renombra solo las columnas
# relevantes del objeto g_ch_sm que queremos añadir.
hedges_g = Hedges_g, # Renombra la columna Hedges_g a hedges_g (nombre más amigable).
ci_low = CI_low, # Renombra CI_low a ci_low (límite inferior del IC del tamaño de efecto).
ci_high = CI_high # Renombra CI_high a ci_high (límite superior del IC del tamaño de efecto).
)
) |>
knitr::kable( # knitr::kable() convierte el tibble combinado en una tabla
# formateada para su inclusión en el informe (HTML, PDF, Word).
digits = 4, # digits = 4 indica que los valores numéricos se mostrarán
# con 4 cifras decimales.
caption = "t (2 muestras): Colesterol por fumador (bilateral)"
# caption define el título o leyenda de la tabla en el documento.
) |>
kableExtra::kable_styling(full_width = FALSE)
| estimate | estimate1 | estimate2 | statistic | p.value | parameter | conf.low | conf.high | method | alternative | hedges_g | ci_low | ci_high |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 4.1391 | 238.6458 | 234.5067 | 2.9119 | 0.0036 | 3884.78 | 1.3523 | 6.9258 | Welch Two Sample t-test | two.sided | 0.0933 | 0.0305 | 0.1562 |
# kableExtra::kable_styling() aplica estilos adicionales a la tabla.
# full_width = FALSE evita que la tabla ocupe todo el ancho de la página,
# mejorando la legibilidad y la presentación.
dec_2s_ch <- ifelse(ht_ch_sm$p.value < alpha, "Rechazar H0", "No rechazar H0") # Decisión (ifelse)
paste("Decisión (α = 0.05):", dec_2s_ch, "| p-valor =", signif(ht_ch_sm$p.value, 4)) # Mensaje (paste)
## [1] "Decisión (α = 0.05): Rechazar H0 | p-valor = 0.003612"
Medias por grupo
Estadístico t y p-valor
Intervalo de confianza 95 % para la diferencia
Tamaño de efecto (Hedges’ g)
Conclusiones
Desde el punto de vista estadístico, se rechaza H₀ y se concluye que existe una diferencia significativa en los niveles medios de colesterol entre fumadores y no fumadores. Sin embargo, la diferencia absoluta es muy reducida (≈ 4 mg/dL) y el tamaño de efecto (Hedges’ g ≈ 0.09) es prácticamente trivial.
En términos prácticos o clínicos, estos resultados sugieren que, en esta muestra, el hecho de ser fumador o no no se asocia con una diferencia relevante en el nivel de colesterol total, lo que coincide con los boxplots donde las distribuciones de ambos grupos se superponen ampliamente.
En este bloque comparamos la frecuencia cardíaca media entre fumadores y no fumadores para verificar si los fumadores presentan una HR significativamente mayor, aplicando una prueba t de dos muestras de Welch unilateral derecha (μ_HR,fum > μ_HR,no) con α = 0,05, calculando el tamaño de efecto Hedges’ g con su intervalo de confianza, presentando los resultados en una tabla formateada y generando automáticamente la decisión sobre H₀ (“rechazar” o “no rechazar”) junto con el p-valor correspondiente.
Hipótesis
- H0: μ_HR,fum ≤ μ_HR,no
- H1: μ_HR,fum > μ_HR,no
Parámetro: diferencia de medias poblacionales de HR
por condición de fumador.
Prueba: t de dos muestras (Welch) unilateral
derecha.
Nivel de significancia: α = 0.05.
Tamaño de efecto: Hedges’ g.
Criterio: si p < α ⇒ rechazar
H0.
alpha <- 0.05 # Nivel de significancia (asignación)
aux_hr <- df |> # Prepara datos para t-test (|>)
dplyr::select(grupo = .data[[col_smoker]], # Selecciona grupo fumador (select)
hr = .data[[col_hr]]) |>
dplyr::filter(!is.na(grupo) & !is.na(hr)) # Elimina NAs (filter)
ht_hr_sm <- t.test(hr ~ grupo, data = aux_hr, # t de 2 muestras unilateral derecha (t.test)
alternative = "greater")
g_hr_sm <- effectsize::hedges_g(hr ~ grupo, data = aux_hr) # Tamaño de efecto Hedges g (hedges_g)
broom::tidy(ht_hr_sm) |> # broom::tidy() convierte el objeto de la prueba t (ht_hr_sm)
# en un data frame/tibble ordenado con columnas como estimate,
# statistic, p.value, conf.low, conf.high, etc.
dplyr::bind_cols( # dplyr::bind_cols() une por columnas (side-by-side) el tibble
# anterior con otro tibble que contiene el tamaño de efecto.
g_hr_sm |> # g_hr_sm es el objeto con el resultado de Hedges' g
# calculado por effectsize::hedges_g().
dplyr::select( # dplyr::select() elige y renombra solo las columnas relevantes
# del objeto g_hr_sm para añadirlas a la tabla final.
hedges_g = Hedges_g, # Renombra la columna Hedges_g a hedges_g (nombre más amigable).
ci_low = CI_low, # Renombra CI_low a ci_low (límite inferior del IC de g).
ci_high = CI_high # Renombra CI_high a ci_high (límite superior del IC de g).
)
) |>
knitr::kable( # knitr::kable() convierte el tibble combinado en una tabla
# formateada para el reporte (HTML/PDF/Word).
digits = 4, # digits = 4 indica que los valores numéricos se muestran
# con 4 decimales.
caption = "t (2 muestras, unilateral): HR por fumador"
# caption define el título o leyenda de la tabla en el informe.
) |>
kableExtra::kable_styling(full_width = FALSE)
| estimate | estimate1 | estimate2 | statistic | p.value | parameter | conf.low | conf.high | method | alternative | hedges_g | ci_low | ci_high |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| -1.3754 | 75.0076 | 76.383 | -3.5809 | 0.9998 | 3896.421 | -2.0073 | Inf | Welch Two Sample t-test | greater | -0.1146 | -0.1774 | -0.0518 |
# kableExtra::kable_styling() aplica estilos adicionales a la tabla.
# full_width = FALSE hace que la tabla no ocupe todo el ancho
# de la página, mejorando la presentación.
dec_2s_hr <- ifelse(ht_hr_sm$p.value < alpha, "Rechazar H0", "No rechazar H0") # Decisión (ifelse)
paste("Decisión (α = 0.05):", dec_2s_hr, "| p-valor =", signif(ht_hr_sm$p.value, 4)) # Mensaje (paste)
## [1] "Decisión (α = 0.05): No rechazar H0 | p-valor = 0.9998"
Medias por grupo
estimate1 = 75.0076: frecuencia cardíaca media en el
primer grupo (no fumadores).estimate2 = 76.3830: frecuencia cardíaca media en el
segundo grupo (fumadores).estimate = -1.3754: diferencia de mediasEs decir, en la muestra los fumadores tienen una frecuencia cardíaca ligeramente mayor (≈ 1.4 lpm) que los no fumadores.
Prueba t unilateral
El límite inferior es negativo, lo que indica que la diferencia compatible con los datos apunta a que el grupo de fumadores puede tener una HR mayor.
Decisión.
Decisión (\(\alpha = 0.05\)): No rechazar \(H_0\) \(|\) p-valor = 0.9998
Con un p-valor tan alto, no hay evidencia estadística para afirmar que la frecuencia cardíaca media del primer grupo sea mayor que la del segundo (en la parametrización de la prueba).
Tamaño de efecto (Hedges’ g)
hedges_g = -0.1146 con IC 95 %: \([-0.1774;\ -0.0518]\).En valor absoluto, \(|g| \approx 0.11\), lo que corresponde a un efecto muy pequeño (muy por debajo de 0.2).
Conclusiones.
Los resultados muestran que la diferencia de frecuencia cardíaca entre fumadores y no fumadores es muy pequeña y de magnitud trivial: ≈ 1.4 lpm de diferencia, con un tamaño de efecto prácticamente nulo.
La prueba unilateral, tal como está parametrizada, concluye “No rechazar \(H_0\)”: no se encuentra evidencia estadística de que la frecuencia cardíaca media del grupo tomado como referencia en la prueba sea mayor.
En términos prácticos o clínicos, la condición de fumador/no fumador no se asocia con una diferencia relevante en la frecuencia cardíaca en esta muestra, lo que coincide con la fuerte superposición observada en los boxplots.
[1] R. A. Irizarry and M. I. Love, Data Analysis for the Life Sciences with R. Boca Raton, FL, USA: CRC Press, Taylor & Francis Group, 2017. Recuperado de: Catálogo SIBBILA 201682.
[2] R. Pino Mejías and R. Beltrán Barba, Modelos de Aprendizaje Profundo. Aplicaciones con R y Python (Trabajo Fin de Grado inédito). Sevilla, España: Universidad de Sevilla, 2022. Disponible: https://hdl.handle.net/11441/142752
[3] G. C. Canavos, Probabilidad y estadística: Aplicaciones y métodos, trad. E. G. Urbina Medal; rev. G. J. Valencia Medal. Ciudad de México, México: McGraw-Hill, 1987. Recuperado de: Catálogo SIBBILA, sibila.14304.
[4] J. García, J. M. Molina López, J. García Herrero, A. Berlanga de Jesús, M. Á. Patricio Guisado, Á. L. Bustamante, y W. R. Padilla, Ciencia de datos: Técnicas analíticas y aprendizaje estadístico, un enfoque práctico. Bogotá, Colombia: Alfaomega Colombiana; Altaria Publicaciones, 2018. Recuperado de: Catálogo SIBBILA, sibbila.138355.
[5] S. A. Pernice, “El problema de la reducción dimensional. Análisis de Componentes Principales (PCA),” Revista Mutis, vol. 14, no. 1, pp. 1–21, 2024. doi: 10.21789/22561498.2057. Recuperado de: Catálogo SIBBILA.