Se importan las librerías de CRAN que se van a utilizar
# paquetes
library(readr)
library(BSDA)
library(ggplot2)
library(estadistica)
library(moments)
Se realiza carga de la base de datos y se asigna a la variable smoking
smoking <- read_csv("smoking_health_data_final.csv")
head(smoking, 10)
## # A tibble: 10 × 7
## age sex current_smoker heart_rate blood_pressure cigs_per_day chol
## <dbl> <chr> <chr> <dbl> <chr> <dbl> <dbl>
## 1 54 male yes 95 110/72 NA 219
## 2 45 male yes 64 121/72 NA 248
## 3 58 male yes 81 127.5/76 NA 235
## 4 42 male yes 90 122.5/80 NA 225
## 5 42 male yes 62 119/80 NA 226
## 6 57 male yes 62 107.5/72.5 NA 223
## 7 43 male yes 75 109.5/69 NA 222
## 8 42 male yes 66 123/73 NA 196
## 9 37 male yes 65 123.5/77 NA 188
## 10 49 male yes 93 127.5/81.5 NA 256
Las variables binarias de la base de datos se convierten a factores que dividen las variables en categorías predeterminadas (por ejemplo, pasar de valores de 0 y 1 para la variable “current_smoker” a representarla como “yes” o “no” dependiendo de si el usuario fuma o no)
smoking=as.data.frame(unclass(smoking),
stringsAsFactors = TRUE)
summary(smoking)
## age sex current_smoker heart_rate blood_pressure
## Min. :32.00 female:2081 no :1968 Min. : 44.00 130/80 : 18
## 1st Qu.:42.00 male :1819 yes:1932 1st Qu.: 68.00 120/80 : 17
## Median :49.00 Median : 75.00 110/70 : 15
## Mean :49.54 Mean : 75.69 125/80 : 15
## 3rd Qu.:56.00 3rd Qu.: 82.00 105/70 : 9
## Max. :70.00 Max. :143.00 107/73 : 9
## (Other):3817
## cigs_per_day chol
## Min. : 0.000 Min. :113.0
## 1st Qu.: 0.000 1st Qu.:206.0
## Median : 0.000 Median :234.0
## Mean : 9.169 Mean :236.6
## 3rd Qu.:20.000 3rd Qu.:263.0
## Max. :70.000 Max. :696.0
## NA's :14 NA's :7
Empleando la librería “estadística” se pueden hallar valores que aportan sentido a la base de datos y permiten conocer más a profundidad la base de datos con la que se está trabajando.
N = nrow(smoking)
str(smoking)
## 'data.frame': 3900 obs. of 7 variables:
## $ age : num 54 45 58 42 42 57 43 42 37 49 ...
## $ sex : Factor w/ 2 levels "female","male": 2 2 2 2 2 2 2 2 2 2 ...
## $ current_smoker: Factor w/ 2 levels "no","yes": 2 2 2 2 2 2 2 2 2 2 ...
## $ heart_rate : num 95 64 81 90 62 62 75 66 65 93 ...
## $ blood_pressure: Factor w/ 2317 levels "100.5/62","100.5/66",..: 230 642 869 671 572 143 198 723 709 874 ...
## $ cigs_per_day : num NA NA NA NA NA NA NA NA NA NA ...
## $ chol : num 219 248 235 225 226 223 222 196 188 256 ...
Para el caso del análisis de variables se toma el ratio de frecuencia cardiaca definido en el variable heart_rate. Primero se observan los valores máximos y mínimos
cat("Máximo", max(smoking$heart_rate),
"Mínimo", min(smoking$heart_rate))
## Máximo 143 Mínimo 44
Después de conocer los valores máximos y mínimos pasa a ser relevante conocer el rango de valores de la variable de tal forma que sea posible determinar eventualmente valores atípicos o que generan outliers en el rango. Se observa en la siguiente celda que el rango es consistente con los valores máximo y mínimo hallados anteriormente.
diff(range(smoking$heart_rate)) # Rango
## [1] 99
Los datos de la mediana y media son consistentes con lo arrojado a través del método summary líneas arriba y al calcular la moda como 75 indica que un gran porcentaje de los datos de frecuencia cardiaca corresponden a 75. Esto es consistente considerando que el segundo cuartil o mediana es 75. Se esperaría al analizar los outliers y la búsqueda de sesgos dentro de la base de datos que los datos sean consistentes y la mayoría de registros de frecuencia cardiaca estuvieran alrededor de 75.
# Medidas de tendencia central
print(list(
media = mean(smoking$heart_rate),
mediana = median(smoking$heart_rate),
moda = moda(smoking$heart_rate)
))
## $media
## [1] 75.68897
##
## $mediana
## [1] 75
##
## $moda
## variable.x
## 1 75
A partir de los resultados de la varianza, desviación estándar y el coeficiente de variación es posible determinar que los datos se alejan de la media con una dispersión moderada, lo que indica que hay diferencias apreciables en la frecuencia cardiaca registrada para los diferentes pacientes.
La desviación estándar de 12 indica que la mayoría de los valores de frecuencia cardiaca están aproximadamente 12 latidos alrededor de la media. Eso implica que la mayoría de latidos deberían estar entre 63 y 87.
El coeficiente de variación de 15.87% indica una variabilidad baja-moderada que permite identificar que la frecuencia cardiaca en fumadores no está tan dispersa y que hay diferencias en los valores entre registros pero no son diferencias extremas.
Lo anterior se puede visualizar mejor en las estadísticas de BoxPlot arrojadas para la variable analizada.
## $Varianza
## [1] 144.3693
##
## $Desviacion_standar
## [1] 12.01538
##
## $coeficiente_variacion
## variable
## 1 0.1587
El cálculo del sesgo en los datos se realiza empleando la función de skewness, recordando:
Debido a que el valor es de 0.6, se puede afirmar que los datos están moderadamente sesgados a la derecha sin ser crítico debido a que el sesgo da un valor menor a 1 (que indicaría un sesgo fuerte a la derecha).
skewness(smoking$heart_rate)
## [1] 0.6635542
Los valores arrojados para “stats” al emplear la función de boxplot indican lo siguiente:
Estos datos nos indican que la distribución central de datos es compacta.
El valor de $conf indica el intervalo de confianza de la mediana y permite interpretar que la mediana está entre 74.6 y 75.35, siendo un intervalo estrecho, así que los datos son estables y con buena precisión.
Los datos de los outliers indican que hay un grupo de registros con una frecuencia cardiaca anormalmente alta, lo que posiblemente genera el sesgo a la derecha visto anteriormente. Esto indica, además, que hay pacientes cuyo estado de salud puede no ser el mejor debido a las diferencias alarmantes en los valores de la frecuencia cardiaca.
boxplot.stats(smoking$heart_rate)
## $stats
## [1] 47 68 75 82 103
##
## $n
## [1] 3900
##
## $conf
## [1] 74.6458 75.3542
##
## $out
## [1] 105 104 120 122 110 107 120 110 106 110 125 110 107 120 115 105 110 115 44
## [20] 125 45 140 108 105 110 120 110 143 110 107 110 108 110 106 110 115 125 110
## [39] 105 108 110 107 108 105 122 110 110 110 110 110 110 46 105 104 105 105 120
## [58] 110 105 110 105 45 110 110 120 110 112 120 108 112 105 110 105 130 104 108
## [77] 110 110 110 115 115 110 110 110 110
Los datos mostrados en el diagrama de BoxPlot confirman el análisis de la variable de frecuencia cardiaca realizado anteriormente, mostrando una varianza baja alrededor del valor de 75 con un ligero sesgo a la derecha y outliers que se agrupan más al extremo máximo (derecha) que al extremo de la izquierda o valors mínimos.
# BoxPlot
ggplot(smoking, aes(x=heart_rate))+
geom_boxplot()+
labs(title = "Diagrama de Boxplot",
x="Frecuencia cardiaca en pacientes")
El mismo ejercicio realizado con la variable de frecuencia cardiaca se realiza con la variable de índice de colesterol pero se condensa en una única celda que resume los procesos realizados anteriormente. La interpretación de los resultados arrojados en la siguiente celda son los siguientes:
El colesterol presenta valores entre 113 mg/dL y 696 mg/dL, lo que genera un rango muy amplio de 583 mg/dL lo que indica una población con un variación muy alta en sus niveles de colesterol, con casos que tienen valores muy bajos y casos que tienen valores muy altos.
La distribución es centrada pero con casos extremos. La media (236.6 mg/dL), la mediana (234 mg/dL) y la moda (240 mg/dL) son similares. Esta cercanía indica que lo resigstros de colesterol de la mayoría de pacientes se encuentran arededor de valores “moderados”. Sin embargo es necesario considerar que hay valores de tipo outliers que son muy extremos en la base de datos.
La varianza (1969.17) y la desviación estándar (44.38 mg/dL) reflejan una dispersión moderada-alta respecto a la media. Es decir aunque existe un punto central común, los valores individuales se alejan con frecuencia entre 40 y 50 mg/dL del promedio.
La asimetría positiva de 0.90 indica una distribución asimétrica sesgada hacia la derecha, lo que implica que existen valores altos que empujan la cola ha de la distribución hacia niveles elevados de colesterol, lo que es consistente con la presencia de valores outliers hacia la derecha.
Q1 = 206 mg/dL, Mediana = 234 mg/dL, Q3 = 263 mg/dL,
lo cual señala que el 50% central de la distribución está relativamente concentrado en un intervalo de unos 57 mg/dL, pero acompañado de colas largas con valores extremos que amplían la dispersión total.
cat("Máximo", max(smoking$chol, na.rm = TRUE),
"Mínimo", min(smoking$chol, na.rm = TRUE))
## Máximo 696 Mínimo 113
diff(range(smoking$chol, na.rm = TRUE)) # Rango
## [1] 583
print(list(
media = mean(smoking$chol, na.rm = TRUE),
mediana = median(smoking$chol, na.rm = TRUE),
moda = moda(smoking$chol) # moda no se ve afectada si no usa NA
))
## $media
## [1] 236.5959
##
## $mediana
## [1] 234
##
## $moda
## variable.x
## 1 240
print(list(
Varianza = var(smoking$chol, na.rm = TRUE),
Desviacion_standar = sd(smoking$chol, na.rm = TRUE),
coeficiente_variacion = coeficiente.variacion(smoking$chol)
))
## $Varianza
## [1] 1969.173
##
## $Desviacion_standar
## [1] 44.37537
##
## $coeficiente_variacion
## variable
## 1 0.1875
skewness(smoking$chol, na.rm = TRUE)
## [1] 0.900482
boxplot.stats(smoking$chol)
## $stats
## [1] 124 206 234 263 347
##
## $n
## [1] 3893
##
## $conf
## [1] 232.5566 235.4434
##
## $out
## [1] 391 366 364 361 382 372 350 432 352 380 368 600 354 367 355 410 370 390 464
## [20] 358 385 398 352 355 390 350 351 382 696 392 359 453 371 353 405 352 439 352
## [39] 358 119 410 360 410 113 373 350 363
# BoxPlot
ggplot(smoking, aes(x=chol))+
geom_boxplot()+
labs(title = "Diagrama de Boxplot: Colesterol",
x="índices de colesterol en pacientes")
## Warning: Removed 7 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
Se empla una hipótesis de igualdad de doble cola. Se emplea una función de z-test donde se asume el valor de sigma (o desviación estándar) a partir del cálculo de la desviación estándar en el vector de frecuencia cardiaca en la base de datos.
z.test(
x=smoking$heart_rate,
alternative = "two.sided",
mu = 75,
sigma.x = sd(smoking$heart_rate),
conf.level = 0.95
)
##
## One-sample z-Test
##
## data: smoking$heart_rate
## z = 3.5809, p-value = 0.0003423
## alternative hypothesis: true mean is not equal to 75
## 95 percent confidence interval:
## 75.31188 76.06607
## sample estimates:
## mean of x
## 75.68897
Los datos arrojados muestran que la hipótesis es errónea debido a que el valor de p es menor al valor de alpha (0.05) por una diferencia significativa. Por tanto se rechaza la hipótesis planteada debido a que existe evidencia estadística que demuestra que la media poblacional de la frecuencia cardiaca no es igual a 75.
Se procede a graficar la distribución de frecuencia cardiaca en la población y se grafica la media poblacional.
ggplot(smoking, aes(x=heart_rate))+
geom_histogram(bins = 10,
col="white")+
labs(title="Histograma de edad de pacientes",
x="Clases de las edades",
y="Frecuencia absoluta")+
geom_vline(aes(xintercept = mean(heart_rate)),
color="red",
linetype="dashed")
Tomando en cuenta los resultados arrojados al realizar la prueba de
hipótesis y el gráfico, se evidencia que los valores de Zc, que
corresponden a los límites de las áreas de rechazo se encuentran entre
75.37250 76.00544, por lo que el valor de 75 está por debajo del valor
permitido en el límite. La gráfica confirma que si bien el valor es
cercano a la media en la distribución, éste no representa con suficiente
margen de confianza la media debido a que no ingresa en la zona de
aceptación.
Para este caso se emplea un enfoque parecido al anterior se emplea como función de prueba de hipótesis una prueba unilateral derecha, que comprueba si un valor es mayor a un umbral definido en una prueba de hipótesus de tipo z-test.
z.test(
x = na.omit(smoking$chol),
alternative = "greater",
mu = 200,
sigma.x = sd(na.omit(smoking$chol)),
conf.level = 0.95
)
##
## One-sample z-Test
##
## data: na.omit(smoking$chol)
## z = 51.456, p-value < 2.2e-16
## alternative hypothesis: true mean is greater than 200
## 95 percent confidence interval:
## 235.4261 NA
## sample estimates:
## mean of x
## 236.5959
La función empleada de z-test cambia y se consideran solo los valores no-nulos del vector que contiene los registros de colesterol de la base de datos.
Los datos arrojados muestran que p-valor es menor al valor de alpha, por lo tanto existe suficiente evidencia estadística para rechazar la hipótesis. Los resultados mostrados se pueden visualizar de mejor forma mediante el siguiente gráfico.
ggplot(smoking, aes(x = chol)) +
geom_histogram(aes(y = after_stat(density)),
bins = 20,
fill = "skyblue",
color = "white") +
geom_density(color = "blue", linewidth = 1, na.rm = TRUE) +
geom_vline(xintercept = mean(smoking$chol, na.rm = TRUE),
color = "red",
linetype = "dashed",
linewidth = 1) +
geom_vline(xintercept = 200,
color = "black",
linetype = "solid",
linewidth = 1) +
labs(title = "Distribución del colesterol con media y umbral de 200",
x = "Colesterol (mg/dL)",
y = "Densidad") +
coord_cartesian(clip = "off")
Donde la línea negra marca el punto de referencia para comparar la media muestral y la distribución y la línea roja muestra la media muestral directamente. Se interpreta que la media muestral es mayor que 200.
Primero se procede a separar en una variable las muestras poblacionales indicadas, asignando a una variable un 1 si el índice de colesterol delm registro es mayor a 240 o 0 si es menor y se seleccionan solo los registros que no sean nulos.
smoking$col_alto <- ifelse(smoking$chol > 240, 1, 0)
col_clean <- na.omit(smoking$col_alto)
Luego, se utiliza una prueba de hipótesis para determinar si el 20% de los registros presentan un índice de colesterol mayor ma 240.
z.test(
x = col_clean,
mu = 0.20, # p0: proporción bajo H0 (ej: 20%)
sigma.x = sd(col_clean), # sd muestral (lo quieres forzar)
alternative = "greater", # H1: p > 0.20
conf.level = 0.95
)
##
## One-sample z-Test
##
## data: col_clean
## z = 28.832, p-value < 2.2e-16
## alternative hypothesis: true mean is greater than 0.2
## 95 percent confidence interval:
## 0.41567 NA
## sample estimates:
## mean of x
## 0.4287182
Los resultados indican que la población que presenta un índice de colesterol mayor a 240 es del 28.832% y un valor de p menor al valor de alpha, por lo tanto hay evidencia suficiente para rechazar la hipótesis propuesta.
Los resultados a nivel visual se observa en el siguiente gráfico de distribución del índice de colesterol en la población de la base de datos.
ggplot(smoking, aes(x = chol)) +
geom_histogram(bins = 15,
color = "white",
fill = "skyblue",
alpha = 0.6,
na.rm = TRUE) +
geom_vline(xintercept = 240,
color = "red",
linewidth = 1,
linetype = "dashed") +
labs(
title = "Distribución del colesterol con umbral de 240 mg/dL",
x = "Colesterol (mg/dL)",
y = "Frecuencia"
)
En el gráfico se observa que un porcentaje mayor del 20% de los
registros analizados tiene un índice de colesterol mayor de 240.
Para este caso se emplea un método semejante al visto anteriormente. Primero se divide la variable en la muestra poblacional que se solicita, separando a los registros de las personas fumadoras.
smoking$W <- ifelse(smoking$heart_rate > 100, 1, 0)
W_clean <- na.omit(smoking$W)
Luego se procede a generar la prueba de hipótesis utilizando los datos definidos anteriormente. La desviación estándar se calcula sobre la variable que contiene la población muestral.
z.test(
x = W_clean,
mu = 0.05, # proporción bajo H0
sigma.x = sd(W_clean), # des. estándar muestral de variable 0/1
alternative = "two.sided", # bilateral
conf.level = 0.95
)
##
## One-sample z-Test
##
## data: W_clean
## z = -10.704, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 0.05
## 95 percent confidence interval:
## 0.01905721 0.02863510
## sample estimates:
## mean of x
## 0.02384615
La población muestral arrojada con el valor de p es del 2.38%, que es menor al valor de prueba de la hipótesis (5%). Debido a que el valor de p es demasiado pequeño y mucho menor al valor de alpha, indicando que no es posible ver una proporción tan baja de taquicardia si la verdadera proporción poblacional fuera del 5% se rechaza la hipótesis. Los resultados arrojados indican que la proporción real de personas con taquicardia está entre el 1.9% y el 2.9%. Muy por debajo del 5%.
ggplot(smoking, aes(x = heart_rate, fill = factor(W))) +
geom_density(alpha = 0.5, na.rm = TRUE) +
labs(
title = "Diagrama de densidad de frecuencia cardíaca por taquicardia",
x = "Frecuencia cardíaca (lpm)",
y = "Densidad",
fill = "Taquicardia"
) +
facet_wrap(. ~ W, labeller = labeller(W = c("0" = "Sin taquicardia",
"1" = "Con taquicardia")))
El anterior gráfico muestra que una población pequeña presenta
taquicardia mientras que la gran mayoría de la población no tiene
taquicardia.
Para este caso se emplea una prueba de hipótesis de dos variables. Primero se genera una separación de las variables en dos muestras poblacionales que corresponden a las personas fumadoras y no-fumadoras.
fum <- subset(smoking, current_smoker == "yes")$chol
nofum <- subset(smoking, current_smoker == "no")$chol
Luego se procede a generar una prueba de hipótesis que eval+ua a si hay diferencias relacionadas en los niveles de colesterol de los dos grupos. Se consideran solo los valores no-nulos.
z.test(
x = fum,
y = nofum,
alternative = "two.sided",
sigma.x = sd(fum, na.rm = TRUE),
sigma.y = sd(nofum, na.rm = TRUE),
conf.level = 0.95
)
##
## Two-sample z-Test
##
## data: fum and nofum
## z = -2.9119, p-value = 0.003592
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -6.924969 -1.353149
## sample estimates:
## mean of x mean of y
## 234.5067 238.6458
Los resultados muestran un valor de p mucho menor al valor de alpha, lo que implica que existe una diferencia significativa entre los niveles medios de colesterol entre las poblaciones fumadoras y no fumadoras. Los datos muestran que la población de fumadores presentan valores medios ligeramente menores que los no-fumadores.
ggplot(smoking, aes(x = current_smoker, y = heart_rate, fill = current_smoker)) +
geom_boxplot(alpha = 0.7) +
labs(title = "Comparación de frecuencia cardíaca entre fumadores y no fumadores",
x = "Hábito de fumar",
y = "Frecuencia cardíaca (lpm)") +
theme(legend.position = "none")
Las distribuciones de datos de las personas fumadoras y no fumadoras
considerando las frecuencias cardiacas demustran los resultados
obtenidos.
Se realiza un ejercicio similar al realizado anteriormente dividiendo la base de datos entre los fumadores y no fumadores.
fum <- subset(smoking, current_smoker == "yes")$heart_rate
nofum <- subset(smoking, current_smoker == "no")$heart_rate
Luego, se genera una prueba de hipótesis unilateral que permita identidicar si el índice de frecuencia cardiaca en fumadores es mayor al índice de no.fumadores.
z.test(
x = fum,
y = nofum,
alternative = "greater", # Unilateral a la derecha
sigma.x = sd(fum, na.rm = TRUE),
sigma.y = sd(nofum, na.rm = TRUE),
conf.level = 0.95
)
##
## Two-sample z-Test
##
## data: fum and nofum
## z = 3.5809, p-value = 0.0001712
## alternative hypothesis: true difference in means is greater than 0
## 95 percent confidence interval:
## 0.7436161 NA
## sample estimates:
## mean of x mean of y
## 76.38302 75.00762
Con los anteriores datos se valida que la media de frecuencia cardiaca en fumadores es de 234.5 y en no fumadores es de 238.6. Sin embargo, el valor de p es mayor al valor de alpha debido a que el valor del Z estadístico calculado entra dentro de la zona de aceptación, por lo tanto se acepta la hipótesis realizada.
Se realiza una gráfica comportamental que describe la distribución de datos analizados.
ggplot(smoking, aes(x = current_smoker,
y = heart_rate,
fill = current_smoker)) +
geom_boxplot(alpha = 0.7, color = "black") +
# Punto rojo para la media de cada grupo
stat_summary(fun = mean,
geom = "point",
color = "red",
size = 3) +
labs(
title = "Frecuencia cardíaca: Fumadores vs No fumadores",
x = "Condición de fumador",
y = "Frecuencia cardíaca (bpm)"
) +
theme_minimal() +
theme(legend.position = "none")
El gráfico anterior muestra que la frecuencia cardiaca en ambos grupos
es ligeramente diferente pero no lo suficiente para afirmar que son
distintas considerando el alpha de 5% definido.