En esta parte del taller estaremos revisando como deben estar estructurados los datos para que puedan ser utilizados en el análisis de datos. La estructura de los datos es importante para que las funciones de R puedan procesarlos correctamente.
La estructura básica de los datos es un data frame
, que
es una matriz donde cada columna representa una variable o atributo y
cada fila representa una observación o caso. Las variables pueden ser de
diferentes tipos, como numéricas, categóricas o lógicas.
También veremos como podemos explorar los datos con estadísticas descriptivas y gráficas para verificar su calidad y observar tendencias y propiedades que nos permitan realizar inferencias y pruebas de hipótesis adecuadas.
Utilizaremos de ejemplo tres bases de datos:
Para realizar el manejo y exploración de los datos, vamos a utilizar
el paquete tidyverse
, que incluye herramientas para
manipulación de datos (dplyr
) y visualización
(ggplot2
). Asegúrate de tenerlos instalados en tu ambiente
de R (revisar en Packages
). Si no los tienes instalados,
puedes usar Install
para instalarlos.
Otros paquetes que se instalen deben ir en el siguiente
chunk para ser activados utilizando library()
.
# Cargar el paquete tidyverse
library(tidyverse)
# Cargar el paquete para usar pipe %>%
library(magrittr)
# Cargar el paquete gt para crear tablas elegantes
library(gt)
Experimento en el que suministró un estrógeno a ratas hembras y machos y se midieron los niveles de calcio plasmático (mg/dL).
# Cargar datos desde archivo .csv
calcio_ratas <- read.csv("calcio-ratas.csv")
# Las primeras 6 filas del data frame
head(calcio_ratas)
## caplasma hormona sexo
## 1 16.3 no hembra
## 2 20.4 no hembra
## 3 12.4 no hembra
## 4 15.8 no hembra
## 5 9.5 no hembra
## 6 15.3 no macho
# Estructura del data frame
str(calcio_ratas)
## 'data.frame': 20 obs. of 3 variables:
## $ caplasma: num 16.3 20.4 12.4 15.8 9.5 15.3 17.4 10.9 10.3 6.7 ...
## $ hormona : chr "no" "no" "no" "no" ...
## $ sexo : chr "hembra" "hembra" "hembra" "hembra" ...
EJERCICIOS:
calcio-ratas.csv
usando
View File
y comparar con el objeto
calcio_ratas
que se creó (localizarlo en
Environment
).hormona
?La variable hormona
es de tipo texto (carácter), pero
queremos que sea un factor para poder realizar algunos análisis
estadísticos que lo requieren así.
# Convertir la variable 'hormona' a factor en una nueva columna utilizando el comando mutate()
calcio_ratas <- calcio_ratas %>%
mutate(tratamiento = as.factor(hormona))
# Verificar la estructura del data frame después de la conversión
str(calcio_ratas)
## 'data.frame': 20 obs. of 4 variables:
## $ caplasma : num 16.3 20.4 12.4 15.8 9.5 15.3 17.4 10.9 10.3 6.7 ...
## $ hormona : chr "no" "no" "no" "no" ...
## $ sexo : chr "hembra" "hembra" "hembra" "hembra" ...
## $ tratamiento: Factor w/ 2 levels "no","si": 1 1 1 1 1 1 1 1 1 1 ...
EJERCICIO:
%>%
en el código
anterior?calcio_ratas
después de la conversión de la variable hormona
a
factor?Vamos a calcular la media y desviación estándar del calcio plasmático, agrupando las observaciones por tratamiento y sexo.
# Estadísticas descriptivas de calcio plasmático por tratamiento y sexo
estadisticas_calcio <- calcio_ratas %>%
group_by(tratamiento, sexo) %>%
summarise(
media_calcio = mean(caplasma),
desviacion_calcio = sd(caplasma)
) %>%
ungroup()
estadisticas_calcio
## # A tibble: 4 × 4
## tratamiento sexo media_calcio desviacion_calcio
## <fct> <chr> <dbl> <dbl>
## 1 no hembra 14.9 4.14
## 2 no macho 12.1 4.25
## 3 si hembra 32.5 4.67
## 4 si macho 27.8 4.29
EJERCICIO:
estadisticas_calcio
?gt
El paquete gt
permite crear tablas más elegantes y
personalizadas. Vamos a usarlo para mostrar las estadísticas
descriptivas de una manera más visual, cambiando nombres y el formato de
los resultados.
# tabla con gt cambiando los nombres y ajustando los decimales
estadisticas_calcio %>%
gt() %>%
tab_header(
title = "Tabla 1. Estadísticas de Calcio Plasmático (mg/dL) por Tratamiento con Estrógeno (si o no) y Sexo",
subtitle = "Datos de un estudio sobre el efecto de estrógenos sobre el calcio plasmático en ratas"
) %>%
cols_label(
sexo = "Sexo",
tratamiento = "Tratamiento",
media_calcio = "Media",
desviacion_calcio = "Desv. Est."
) %>%
fmt_number(
columns = vars(media_calcio, desviacion_calcio),
decimals = 2
)
Tabla 1. Estadísticas de Calcio Plasmático (mg/dL) por Tratamiento con Estrógeno (si o no) y Sexo | |||
Datos de un estudio sobre el efecto de estrógenos sobre el calcio plasmático en ratas | |||
Tratamiento | Sexo | Media | Desv. Est. |
---|---|---|---|
no | hembra | 14.88 | 4.14 |
no | macho | 12.12 | 4.25 |
si | hembra | 32.52 | 4.67 |
si | macho | 27.78 | 4.29 |
EJERCICIOS:
gt
. La fórmula para el error estándar de la media es:
sd(caplasma) / sqrt(n())
.Una de las formas de visualizar los datos de estadísticas descriptiva
es mediante gráficos. Vamos a crear un gráfico de barras que muestre la
media del calcio plasmático según el tratamiento y el sexo y la
desviación estándar como líneas. Utilizaremos ggplot2
para
crear el gráfico.
# Gráfica de barras separadas de calcio plasmático por tratamiento y sexo usando los datos de calcio-ratas.csv
bar_calcio <- ggplot(estadisticas_calcio, aes(x = tratamiento, y = media_calcio, fill = sexo)) +
geom_bar(stat = "identity", position = "dodge") +
geom_errorbar(aes(ymin = media_calcio - desviacion_calcio, ymax = media_calcio + desviacion_calcio), width = 0.2, position = position_dodge(0.9)) +
labs(
x = "Tratamiento con Estrógeno",
y = "Calcio Plasmático, mg/dL"
) +
scale_fill_manual(values = c("lightblue", "red"))
bar_calcio
Figura 1. Media del calcio plasmático (mg/dL) con su desviación estándar, según tratamiento y sexo de las ratas.
EJERCICIOS:
En este caso, vamos a trabajar con un conjunto de datos que contiene información sobre mujeres de la etnia Pima y variables asociadas a la diabetes. Vamos a cargar los datos desde un archivo CSV y realizar algunas estadísticas descriptivas.
La metadata (descripción de las variables y sus unidades) de este conjunto de datos se puede encontrar en el siguiente enlace: Pima Indians Diabetes Database Metadata.
# Cargar datos desde archivo .csv
diabetes <- read.csv("diabetes.csv")
# Las primeras 6 filas del data frame
head(diabetes)
## Pregnancies Glucose BloodPressure SkinThickness Insulin BMI
## 1 6 148 72 35 0 33.6
## 2 1 85 66 29 0 26.6
## 3 8 183 64 0 0 23.3
## 4 1 89 66 23 94 28.1
## 5 0 137 40 35 168 43.1
## 6 5 116 74 0 0 25.6
## DiabetesPedigreeFunction Age Outcome
## 1 0.627 50 1
## 2 0.351 31 0
## 3 0.672 32 1
## 4 0.167 21 0
## 5 2.288 33 1
## 6 0.201 30 0
# Estructura del data frame
str(diabetes)
## 'data.frame': 768 obs. of 9 variables:
## $ Pregnancies : int 6 1 8 1 0 5 3 10 2 8 ...
## $ Glucose : int 148 85 183 89 137 116 78 115 197 125 ...
## $ BloodPressure : int 72 66 64 66 40 74 50 0 70 96 ...
## $ SkinThickness : int 35 29 0 23 35 0 32 0 45 0 ...
## $ Insulin : int 0 0 0 94 168 0 88 0 543 0 ...
## $ BMI : num 33.6 26.6 23.3 28.1 43.1 25.6 31 35.3 30.5 0 ...
## $ DiabetesPedigreeFunction: num 0.627 0.351 0.672 0.167 2.288 ...
## $ Age : int 50 31 32 21 33 30 26 29 53 54 ...
## $ Outcome : int 1 0 1 0 1 0 1 0 1 1 ...
EJERCICIOS:
Vamos a cambiar los nombres de las variables para que sean más cortos
y sencillos de recordar. A veces esto es importante si los nombres de la
columnas contienen espacios y caracteres especiales o si son muchos.
Utilizaremos la función rename()
del paquete
dplyr
.
Debemos utilizar otro nombre para el nuevo data frame, ya que si usamos el mismo nombre, se sobrescribirá el objeto original y perderemos la metadata original.
diabetes_n
: cambio de nombres de variables.
# Cambiar nombres de columnas
diabetes_n <- diabetes %>%
rename(
edad = Age,
embarazos = Pregnancies,
glucosa = Glucose,
presion = BloodPressure,
pliegues = SkinThickness,
insulina = Insulin,
imc = BMI,
gen_diabetes = DiabetesPedigreeFunction,
edad_diagnostico = Age,
diabetes = Outcome
)
head(diabetes_n)
## embarazos glucosa presion pliegues insulina imc gen_diabetes
## 1 6 148 72 35 0 33.6 0.627
## 2 1 85 66 29 0 26.6 0.351
## 3 8 183 64 0 0 23.3 0.672
## 4 1 89 66 23 94 28.1 0.167
## 5 0 137 40 35 168 43.1 2.288
## 6 5 116 74 0 0 25.6 0.201
## edad_diagnostico diabetes
## 1 50 1
## 2 31 0
## 3 32 1
## 4 21 0
## 5 33 1
## 6 30 0
EJERCICIOS:
diabetes_n4
con los nombres de las
variables con solo cuatro letras.Vamos a crear dos nuevos conjuntos de datos: uno de las diagnosticadas con diabetes y otro de las que no tienen diabetes.
# Filtrar datos de acuerdo al diagnóstico de diabetes
diabetes_si <- diabetes_n %>%
filter(diabetes == 1)
diabetes_no <- diabetes_n %>%
filter(diabetes == 0)
# guardar en archivos .csv sin numero de fila
write.csv(diabetes_si, "diabetes_si.csv", row.names = FALSE)
write.csv(diabetes_no, "diabetes_no.csv", row.names = FALSE)
EJERCICIO:
diabetes_30plus_si.csv
que contenga las
mujeres de 30 años o más diagnosticadas con diabetes.Vamos a calcular algunas estadísticas descriptivas de las variables
numéricas del data frame diabetes_n
y a identificar valores
no válidos (como 0 en variables que no deberían tener ese valor, como
glucosa, insulina e IMC).
Para esto vamos a utilizar un comando general de R
(summary
) para obtener estadísticas descriptivas de las
variables numéricas de todo el data frame.
# Estadísticas descriptivas de las variables numéricas
summary(diabetes_n)
## embarazos glucosa presion pliegues
## Min. : 0.000 Min. : 0.0 Min. : 0.00 Min. : 0.00
## 1st Qu.: 1.000 1st Qu.: 99.0 1st Qu.: 62.00 1st Qu.: 0.00
## Median : 3.000 Median :117.0 Median : 72.00 Median :23.00
## Mean : 3.845 Mean :120.9 Mean : 69.11 Mean :20.54
## 3rd Qu.: 6.000 3rd Qu.:140.2 3rd Qu.: 80.00 3rd Qu.:32.00
## Max. :17.000 Max. :199.0 Max. :122.00 Max. :99.00
## insulina imc gen_diabetes edad_diagnostico
## Min. : 0.0 Min. : 0.00 Min. :0.0780 Min. :21.00
## 1st Qu.: 0.0 1st Qu.:27.30 1st Qu.:0.2437 1st Qu.:24.00
## Median : 30.5 Median :32.00 Median :0.3725 Median :29.00
## Mean : 79.8 Mean :31.99 Mean :0.4719 Mean :33.24
## 3rd Qu.:127.2 3rd Qu.:36.60 3rd Qu.:0.6262 3rd Qu.:41.00
## Max. :846.0 Max. :67.10 Max. :2.4200 Max. :81.00
## diabetes
## Min. :0.000
## 1st Qu.:0.000
## Median :0.000
## Mean :0.349
## 3rd Qu.:1.000
## Max. :1.000
EJERCICIO:
Vamos a filtrar los datos para eliminar los valores no válidos de las
variables: glucosa
, presion
,
pliegues
, insulina
e imc
y crear
un nuevo data frame diabetes_nfilt
.
# Filtrar datos para eliminar valores no válidos
diabetes_nfilt <- diabetes_n %>%
filter(glucosa != 0 & presion != 0 & pliegues != 0 & insulina != 0 & imc != 0)
# Ver la estructura del nuevo data frame
str(diabetes_nfilt)
## 'data.frame': 392 obs. of 9 variables:
## $ embarazos : int 1 0 3 2 1 5 0 1 1 3 ...
## $ glucosa : int 89 137 78 197 189 166 118 103 115 126 ...
## $ presion : int 66 40 50 70 60 72 84 30 70 88 ...
## $ pliegues : int 23 35 32 45 23 19 47 38 30 41 ...
## $ insulina : int 94 168 88 543 846 175 230 83 96 235 ...
## $ imc : num 28.1 43.1 31 30.5 30.1 25.8 45.8 43.3 34.6 39.3 ...
## $ gen_diabetes : num 0.167 2.288 0.248 0.158 0.398 ...
## $ edad_diagnostico: int 21 33 26 53 59 51 31 33 32 27 ...
## $ diabetes : int 0 1 1 1 1 1 1 0 1 0 ...
# usar summary para verificar que no hay valores no válidos
summary(diabetes_nfilt)
## embarazos glucosa presion pliegues
## Min. : 0.000 Min. : 56.0 Min. : 24.00 Min. : 7.00
## 1st Qu.: 1.000 1st Qu.: 99.0 1st Qu.: 62.00 1st Qu.:21.00
## Median : 2.000 Median :119.0 Median : 70.00 Median :29.00
## Mean : 3.301 Mean :122.6 Mean : 70.66 Mean :29.15
## 3rd Qu.: 5.000 3rd Qu.:143.0 3rd Qu.: 78.00 3rd Qu.:37.00
## Max. :17.000 Max. :198.0 Max. :110.00 Max. :63.00
## insulina imc gen_diabetes edad_diagnostico
## Min. : 14.00 Min. :18.20 Min. :0.0850 Min. :21.00
## 1st Qu.: 76.75 1st Qu.:28.40 1st Qu.:0.2697 1st Qu.:23.00
## Median :125.50 Median :33.20 Median :0.4495 Median :27.00
## Mean :156.06 Mean :33.09 Mean :0.5230 Mean :30.86
## 3rd Qu.:190.00 3rd Qu.:37.10 3rd Qu.:0.6870 3rd Qu.:36.00
## Max. :846.00 Max. :67.10 Max. :2.4200 Max. :81.00
## diabetes
## Min. :0.0000
## 1st Qu.:0.0000
## Median :0.0000
## Mean :0.3316
## 3rd Qu.:1.0000
## Max. :1.0000
EJERCICIO:
diabetes_nfilt
?Vamos a calcular las estadísticas descriptivas media y desviación
estándar de las variables glucosa
e insulina
agrupadas por el diagnóstico de diabetes. Pero antes debemos filtrar los
datos para eliminar los valores no válidos de estas dos variables
solamente.
# Estadísticas descriptivas de glucosa e insulina por diagnóstico de diabetes con filtrado !=0
estadisticas_diabetes <- diabetes_n %>%
filter(glucosa != 0 & insulina != 0) %>%
group_by(diabetes) %>%
summarise(
media_glucosa = round(mean(glucosa),1),
desviacion_glucosa = round(sd(glucosa),1),
media_insulina = round(mean(insulina),1),
desviacion_insulina = round(sd(insulina),1)
)
estadisticas_diabetes
## # A tibble: 2 × 5
## diabetes media_glucosa desviacion_glucosa media_insulina desviacion_insulina
## <int> <dbl> <dbl> <dbl> <dbl>
## 1 0 112. 24.6 131. 102.
## 2 1 145. 29.8 207. 133.
EJERCICIO:
round()
en el código
anterior? ¿Qué hace exactamente?Vamos a crear una tabla más elegante con gt
para mostrar
las estadísticas descriptivas de glucosa e insulina por diagnóstico de
diabetes.
# tabla con gt cambiando los nombres
estadisticas_diabetes %>%
gt() %>%
tab_header(
title = "Tabla 2. Estadísticas de Glucosa e Insulina por Diagnóstico de Diabetes.",
subtitle = "Datos de mujeres de la etnia Pima en Arizona"
) %>%
cols_label(
diabetes = "Diagnóstico",
media_glucosa = "Media Glucosa",
desviacion_glucosa = "D. E. Glucosa",
media_insulina = "Media Insulina",
desviacion_insulina = "D. E. Insulina"
)
Tabla 2. Estadísticas de Glucosa e Insulina por Diagnóstico de Diabetes. | ||||
Datos de mujeres de la etnia Pima en Arizona | ||||
Diagnóstico | Media Glucosa | D. E. Glucosa | Media Insulina | D. E. Insulina |
---|---|---|---|---|
0 | 111.5 | 24.6 | 130.7 | 102.5 |
1 | 145.2 | 29.8 | 206.8 | 132.7 |
EJERCICIO:
Vamos a crear un histograma de la variable glucosa
para
visualizar su distribución de valores. Utilizaremos ggplot2
para crear el gráfico.
# Filtrar datos para eliminar valores no válidos de glucosa
diabetes_glucosa <- diabetes_n %>%
filter(glucosa != 0)
# Histograma de glucosa
histograma_glucosa <- ggplot(diabetes_glucosa, aes(x = glucosa)) +
geom_histogram(binwidth = 5, fill = "lightblue", color = "black") +
labs(
x = "Glucosa (mg/dL)",
y = "Frecuencia"
) +
theme_minimal()
histograma_glucosa
Figura 2. Histograma de la variable glucosa (mg/dL) del estudio de diabetes en las mujeres de la etnia Pima.
EJERCICIOS:
insulina
y cambia el
color de las barras a rojo. Utiliza un ancho de barra de 10.Vamos a crear un gráfico de caja y bigoye (‘box & whisker plot’)
para visualizar la distribución de la variable glucosa
según el diagnóstico de diabetes. Esto nos permitirá observar la
mediana, cuartiles y posibles valores atípicos.
# Gráfico de caja de glucosa por diagnóstico de diabetes, filtrando valores no válidos (0), incluyendo la media con un punto rojo y usando jitter para mostrar los puntos individuales
boxplot_glucosa <- ggplot(diabetes_nfilt, aes(x = factor(diabetes), y = glucosa)) +
geom_boxplot(outlier.colour = "red", outlier.size = 2, fill = "lightblue") +
geom_jitter(color = "darkblue", alpha = 0.5, width = 0.2) +
geom_point(stat = "summary", fun = "mean", color = "red", size = 3) +
labs(
x = "Diagnóstico de Diabetes",
y = "Glucosa (mg/dL)"
) +
scale_x_discrete(labels = c("0" = "No Diabetes", "1" = "Diabetes")) +
theme_minimal()
boxplot_glucosa
Figura 3. Gráfico de caja y bigote de la variable glucosa (mg/dL) por diagnóstico de diabetes en las mujeres de la etnia Pima.
EJERCICIOS:
geom_jitter()
en el gráfico de caja?
¿Qué efecto tiene en la visualización de los datos?insulina
por
diagnóstico de diabetes, incluyendo la media con un punto rojo y usando
jitter
para mostrar los puntos individuales.Vamos a crear una nueva variable que sea el índice de glucosa/insulina, que es la relación entre los niveles de glucosa e insulina. Esta variable puede ser útil para analizar la resistencia a la insulina.
# Crear nueva variable índice glucosa/insulina
diabetes_gi <- diabetes_n %>%
filter(insulina != 0 & glucosa != 0) %>%
mutate(indice_gi = glucosa / insulina)
head(diabetes_gi)
## embarazos glucosa presion pliegues insulina imc gen_diabetes
## 1 1 89 66 23 94 28.1 0.167
## 2 0 137 40 35 168 43.1 2.288
## 3 3 78 50 32 88 31.0 0.248
## 4 2 197 70 45 543 30.5 0.158
## 5 1 189 60 23 846 30.1 0.398
## 6 5 166 72 19 175 25.8 0.587
## edad_diagnostico diabetes indice_gi
## 1 21 0 0.9468085
## 2 33 1 0.8154762
## 3 26 1 0.8863636
## 4 53 1 0.3627993
## 5 59 1 0.2234043
## 6 51 1 0.9485714
Vamos a visualizar la distribución del índice glucosa/insulina con un histograma.
# Histograma del índice glucosa/insulina
histograma_gi <- ggplot(diabetes_gi, aes(x = indice_gi)) +
geom_histogram(binwidth = 0.2, fill = "lightgreen", color = "black") +
labs(
x = "Índice Glucosa/Insulina",
y = "Frecuencia"
) +
theme_minimal()
histograma_gi
Figura 4. Histograma del índice glucosa/insulina en las mujeres de la etnia Pima.
Vamos a extraer el caso con el índice glucosa/insulina más alto.
# Extraer el caso con el índice glucosa/insulina más alto
max_gi <- diabetes_gi %>%
filter(indice_gi == max(indice_gi))
max_gi
## embarazos glucosa presion pliegues insulina imc gen_diabetes
## 1 0 180 78 63 14 59.4 2.42
## edad_diagnostico diabetes indice_gi
## 1 25 1 12.85714
EJERCICIOS:
Vamos a crear un gráfico de dispersión que muestre la relación entre los niveles de glucosa e insulina, diferenciando por diagnóstico de diabetes. Esto nos permitirá observar si hay alguna tendencia o patrón en los datos.
# Gráfico de dispersión de glucosa e insulina por diagnóstico de diabetes
scatter_glucosa_insulina <- ggplot(diabetes_gi, aes(x = glucosa, y = insulina, color = factor(diabetes))) +
geom_point(alpha = 0.5) +
labs(
x = "Glucosa (mg/dL)",
y = "Insulina (μU/mL)",
color = "Diagnóstico"
) +
scale_color_manual(values = c("blue", "red"), labels = c("No Diabetes", "Diabetes")) +
theme_minimal()
scatter_glucosa_insulina
Figura 5. Gráfico de dispersión de glucosa e insulina por diagnóstico de diabetes en las mujeres de la etnia Pima.
EJERCICIOS: