Capítulo 2 Análisis univariado
2.1 Caso: Encuesta a médicos y enfermeros.
En esta sesión veremos la exploración de variables cuantitativas utilizando medidas de resumen y gráficos de caja.
Antes de comenzar, verificamos si tenemos instalados los paquetes necesarios. Para ello, copiamos el siguiente código en la consola y lo ejecutamos verificando que ningún error aparezca. El mensaje de error puede identificarse porque comienza con la palabra “Error.”
Es posible observar mensajes o advertencias (warnings) en rojo sin que sean errores.
library(haven)
library(DT)
library(skimr)
2.1.1 Lectura de datos.
Utilizaremos el conjunto de datos de la encuesta nacional a médicos y enfermeros para obtener los datos para este análisis. Para ello, abrimos los datos con el siguiente código:
# Encuesta Nacional ENSUSALUD 2015 a medicos y enfermeros
<- "http://portal.susalud.gob.pe/wp-content/uploads/archivo/base-de-datos/2015/CUESTIONARIO%2002%20-%20CAPITULOS.sav"
enlace = haven::read_sav(enlace) datos
Despues de ejecutar esto, notará que en la sección Enviroment aparece el objeto datos.
2.1.2 Exploración básica
En esta primera parte, realizamos una exploración inicial del dataset. Con el comando head
observamos las primeras 6 filas para conocer inicialmente el dataset. Otra opcion dar click al dataset “datos” en la ventana de environment. Verá que aparece una nueva ventana con el dataset.
head(datos[,1:10]) # Observar los primeros 6
## # A tibble: 6 x 10
## ID USUARIOID CCDD DEPARTAMENTO CCPP PROVINCIA CCDI DISTRITO cccp nombreCP
## <dbl> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 1 EVAL3 01 AMAZONAS 01 CHACHAPOYAS 01 CHACHAPOYAS 0001 CHACHAPOYAS
## 2 1 EVAL3 01 AMAZONAS 01 CHACHAPOYAS 01 CHACHAPOYAS 0001 CHACHAPOYAS
## 3 1 EVAL3 01 AMAZONAS 01 CHACHAPOYAS 01 CHACHAPOYAS 0001 CHACHAPOYAS
## 4 1 EVAL3 01 AMAZONAS 01 CHACHAPOYAS 01 CHACHAPOYAS 0001 CHACHAPOYAS
## 5 1 EVAL3 01 AMAZONAS 01 CHACHAPOYAS 01 CHACHAPOYAS 0001 CHACHAPOYAS
## 6 1 EVAL3 01 AMAZONAS 01 CHACHAPOYAS 01 CHACHAPOYAS 0001 CHACHAPOYAS
# View(datos)
Utilizamos el siguiente código para observar la lista completa de preguntas utilizadas al recolectar estos datos.
<- sapply(datos, attr,"label")
etiquetas_todos ::datatable(data.frame(etiquetas_todos)) DT
Puede observar que existe un buscador en esta tabla. Este buscador ayudará a buscar las variables que necesitemos.
Ahora, exploramos las variables de interés: profesión y edad.
Utilizamos la función attr con el argumento “label” para observar la variable C2P1 asociada a la profesión.
attr(datos$C2P1,"label")
## [1] "¿CUÁL ES SU PROFESIÓN?"
Los códigos y etiquetas de las posibles respuestas para esta variable los observamos a continuación.
attr(datos$C2P1,"labels")
## Médico Enfermero/a
## 1 2
attr(datos$C2P1,"label")
## [1] "¿CUÁL ES SU PROFESIÓN?"
De estos resultados, se observa que la profesión enfermero esta asociada al código 2 mientras que la profesión de médico al código 1.
Utilizamos esta información para filtrar los datos correspondientes a los médicos (código 1).
= datos[datos$C2P1==1,]
data_medicos dim(data_medicos)
## [1] 2219 270
2.1.3 Análisis univariado
En esta sección, veremos ejemplos del análisis univariado para la variables edad.
2.1.3.1 Medidas de resumen.
Las medidas de resumen me sirven para resumir la información de una variable.
Comenzaremos utilizando una tabla de frecuencias sin agrupar para observar todos los posibles valores de la edad.
table(data_medicos$C2P2EDAD)
##
## 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
## 1 1 9 27 46 39 52 60 47 60 70 72 53 68 68 53 58 52 70 60 52 57 65 56 59 56 55 46 50 55 53 56
## 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 79 81 85 88
## 67 61 63 50 60 64 46 46 40 17 25 20 11 9 1 2 1 1 1 2 1 1 2 1 1
Como la edad en años es una variable cuantitativa discreta con muchos valores, una tabla de frecuencias no ayuda a resumir la información. Es mejor resumir esta información con medidas de tendencia central, dispersión y asimetría.
2.1.3.1.1 Medidas de tendencia central.
# Media
mean(data_medicos$C2P2EDAD)
## [1] 46.44795
# Mediana
median(data_medicos$C2P2EDAD)
## [1] 46
Interpretación:
- La edad promedio de los médicos es 46.4479495 años, y su mediana 46 años. A partir de la mediana, podemos también decir lo siguiente: 50% de los médicos tienen hasta 46 años.
2.1.3.1.2 Medidas de posición.
# Cuantiles (Cuartiles)
quantile(data_medicos$C2P2EDAD,probs=c(0.25,0.75,0.1,0.9))
## 25% 75% 10% 90%
## 37 56 31 62
Interpretación:
- El 25% de los medicos más jóvenes tienen hasta 37 años.
- El 75% de los medicos más jóvenes tienen hasta 56 años.
- El 10% de los medicos más jóvenes tienen hasta 31 años.
- El 19% de los medicos más jóvenes tienen hasta 62 años.
2.1.3.1.3 Medidas de dispersión.
Rango
# Rango
<- range(data_medicos$C2P2EDAD)
rg rg
## [1] 24 88
2] - rg[1] rg[
## [1] 64
Interpretación:
- Las edades de los médicos están entre 24 y 88 años. Además, el rango de sus edades es de 64 años.
Rango intercuartílico.
# Vemos los cuartiles.
quantile(data_medicos$C2P2EDAD,probs=c(0.25,0.5,0.75))
## 25% 50% 75%
## 37 46 56
# calculo rápido del rango intercuartil
IQR(data_medicos$C2P2EDAD)
## [1] 19
Interpretación:
- El rango intercuartílico de las edades es de 19 años.
- El 50% de los médicos tienen entre 37 y 56 años.
Desviación estandard.
# Desviación estandard
sd(data_medicos$C2P2EDAD)
## [1] 11.38578
Interpretación:
+ La desviación estandard para la edad de los médicos es 11.39 años.
Esto quiere decir que, en promedio, las edades se desvian 11.39 años con respecto a la media (46.45 años).
Coeficiente de variación.
# Coeficiente de variación
<- sd(data_medicos$C2P2EDAD)/mean(data_medicos$C2P2EDAD)
CV CV
## [1] 0.2451299
Interpretación:
- El coeficiente de variación es 0.25 (o 25%). Es decir, los datos de las edades tienen una desviación estandard de 25% de la media de las edades de los médicos.
Note que no utilizamos unidades para el coeficiente de variación. Este indicador es adimensional.
2.1.3.1.4 Medidas de asimetría.
# Asimetria
= function(x) mean((x - mean(x))^3)/sd(x)^3
Fisher.asi = function(x) 3*(mean(x) - median(x))/sd(x)
Pearson.asi
Fisher.asi(data_medicos$C2P2EDAD)
## [1] 0.143489
Pearson.asi(data_medicos$C2P2EDAD)
## [1] 0.1180287
A partir de los coeficientes de asimetría concluímos que los datos de edades para los médicos tienen cola a la derecha. (A mayor coeficiente de asimetría se observará mayor dispersión hacia un lado de la distribución)
2.1.3.1.5 Utilitarios en R
2.1.3.1.5.1 Comando summary
El comando summary nos servirá para conocer medidas de resumen básicas para una variable.
# Resumen de la variable edad
summary(data_medicos$C2P2EDAD)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 24.00 37.00 46.00 46.45 56.00 88.00
Podemos observar el minimo y máximo; el primer(1st Qu) y tercer cuartil(3rd Qu); y medidas de tendencia central: media y mediana.
2.1.3.1.5.2 Librería skimr
Podemos realizar un análisis univarido de manera rápida utilizando la librería skimr
. Recuerde instalar previamente la librería escribiendo install.packages("skimr")
en la consola si se utiliza por primera vez.
Con el comando skim
observaremos algunas medidas de tendencia central, dispersión y posición. Estas nos darán una vista general de los datos.
Nota: Podría demorar en ejecutarse si el dataset tiene muchas variables (columnas).
Probar el siguiente comando en la consola:
library(skimr)
::skim(datos[,1:20]) skimr
2.1.3.1.6 Observaciones sobre la media y mediana.
La mediana minimiza la siguiente función:
\[ f_1(z) = \sum^{n}_{i=1}(|X_i - z|) \]$
Y la media, por otro lado, minimiza la siguiente función:
\[ f_2(z) = \sum^{n}_{i=1}((X_i - z)^2) \] Ambas funciones son sumatorias de las desviaciones con respecto a z. Por ello, ambas indican la suma de errores que hay con respecto al valor z.
Observamos gráficamente estas funciones:
- Función 1: Función minimizada con la mediana.
# Definimos la funcion1 en R:
<- function(x) sum(abs(data_medicos$C2P2EDAD - x))
funcion1 funcion1(1)
## [1] 100849
funcion1(2)
## [1] 98630
# Graficamos la función:
<- seq(20,90,1)
y <- apply(array(y),1,funcion1)
fy plot(y,fy,type="l",xlab="Edad",ylab="Función de pérdida")
# Añadimos el punto correspondiente a la mediana
points(x=median(data_medicos$C2P2EDAD),
y=funcion1(46),lwd=5,col=2)
- Función 2: Función minimizada con la media.
# Definición de la función
<- function(x) sum((data_medicos$C2P2EDAD - x)^2)
funcion2 funcion2(1)
## [1] 4870913
funcion2(2)
## [1] 4671434
# Gráfica
<- seq(20,90,1)
y <- apply(array(y),1,funcion2)
fy plot(y,fy,xlab="Edad",ylab="Función de pérdida",type="l")
# Punto correspondiente a la media:
points(x=mean(data_medicos$C2P2EDAD),
y=funcion2(mean(data_medicos$C2P2EDAD)),lwd=5,col=2)
2.1.3.2 Gráficos
2.1.3.2.1 Histogramas
Básicos
Los histogramas se crean con la función “hist.”
<- hist(data_medicos$C2P2EDAD,
histo1 xlab = "Edad",
ylab = "Frencuencia",
main = "")
Tablas de frecuencia agrupadas.
A partir del histograma, se puede crear la tabla de frecuencias agrupada. En el siguiente código, utilizamos la categorización de la variable edad del histograma para crear la tabla de frecuencias agrupadas.
library(summarytools)
<- histo1$breaks # Obtiene los cortes para la variable a partir del histograma
cortes <- cut(data_medicos$C2P2EDAD, cortes) #Crea la variable categorizada
variable_categorizada freq(variable_categorizada) # Muestra la tabla de frecuencias
## Frequencies
## variable_categorizada
## Type: Factor
##
## Freq % Valid % Valid Cum. % Total % Total Cum.
## ------------- ------ --------- -------------- --------- --------------
## (20,25] 2 0.090 0.090 0.090 0.090
## (25,30] 173 7.796 7.886 7.796 7.886
## (30,35] 309 13.925 21.812 13.925 21.812
## (35,40] 300 13.520 35.331 13.520 35.331
## (40,45] 291 13.114 48.445 13.114 48.445
## (45,50] 291 13.114 61.559 13.114 61.559
## (50,55] 260 11.717 73.276 11.717 73.276
## (55,60] 301 13.565 86.841 13.565 86.841
## (60,65] 213 9.599 96.440 9.599 96.440
## (65,70] 66 2.974 99.414 2.974 99.414
## (70,75] 7 0.315 99.730 0.315 99.730
## (75,80] 2 0.090 99.820 0.090 99.820
## (80,85] 3 0.135 99.955 0.135 99.955
## (85,90] 1 0.045 100.000 0.045 100.000
## <NA> 0 0.000 100.000
## Total 2219 100.000 100.000 100.000 100.000
Densidad aproximada.
En el hisgrama es posible observar, además de la frecuencia, la densidad en el eje y. La densidad es un indicador similar al de la proporción pero que viene multiplicado por la inversa de la amplitud del intervalo. En R, esta densidad es calculada automaticamente con el argumento prob=T
cuando se crea el histograma.
# Graficamos la densidad
hist(data_medicos$C2P2EDAD,
xlab = "Edad",
ylab = "Densidad",
main = "",
prob = T)
Otra forma de ver la densidad es guardando el histograma en el objeto hist.1 de la siguiente manera:
# Otra forma: guardando el histograma en el objeto hist.1
.1 = hist(data_medicos$C2P2EDAD,
histxlab = "Edad",
ylab = "Densidad",
main = "",
prob = T)
.1 hist
## $breaks
## [1] 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90
##
## $counts
## [1] 2 173 309 300 291 291 260 301 213 66 7 2 3 1
##
## $density
## [1] 1.802614e-04 1.559261e-02 2.785038e-02 2.703921e-02 2.622803e-02 2.622803e-02 2.343398e-02
## [8] 2.712934e-02 1.919784e-02 5.948626e-03 6.309148e-04 1.802614e-04 2.703921e-04 9.013069e-05
##
## $mids
## [1] 22.5 27.5 32.5 37.5 42.5 47.5 52.5 57.5 62.5 67.5 72.5 77.5 82.5 87.5
##
## $xname
## [1] "data_medicos$C2P2EDAD"
##
## $equidist
## [1] TRUE
##
## attr(,"class")
## [1] "histogram"
# Observemos el cálculo de la densidad para el primer intervalo.
= (1/(25-20))*(2/2219)
f1 f1
## [1] 0.0001802614
# Compararlo con lo obtenido con el histograma:
.1$density hist
## [1] 1.802614e-04 1.559261e-02 2.785038e-02 2.703921e-02 2.622803e-02 2.622803e-02 2.343398e-02
## [8] 2.712934e-02 1.919784e-02 5.948626e-03 6.309148e-04 1.802614e-04 2.703921e-04 9.013069e-05
2.1.3.2.1.1 Comparar grupos con histogramas:
Los histogramas podemos usarlos también para comparar dos grupos. En estos casos, debemos asegurarnos de que los ejes x e y tengan las misma escala en ambos gráficos. En el siguiente gráfico definimos la escala con el argumento xlim=c(20,90)
.
<- par(mfrow=c(2,1)) # Crear un arreglo de gráficos.
x1 hist(data_medicos$C2P2EDAD[data_medicos$C2P4==1],
xlab = "Edad",
ylab = "Densidad",main="Hombres",
xlim=c(20,90),
prob = T)
hist(data_medicos$C2P2EDAD[data_medicos$C2P4==2],
xlab = "Edad",
ylab = "Densidad",main="Mujer",
xlim=c(20,90),
prob = T)
2.1.3.2.2 Gráficos de densidad.
La aproximación de la función de densidad de una variable se realiza utilizando el comando “density.”
# Densidad
hist(data_medicos$C2P2EDAD,
xlab = "Edad",
ylab = "Densidad",main="",
prob = T)
lines(density(data_medicos$C2P2EDAD))
Si deseamos utilizarla sin el histograma podemos utilizar lo siguiente:
# Densidad
plot((density(data_medicos$C2P2EDAD)),
xlab = "Edad",
ylab = "Densidad",
main="")
Es util para para realizar comparaciones entre dos grupos(Análisis bivariado).
plot(density(data_medicos$C2P2EDAD[data_medicos$C2P4==1]),
main = "",xlab="Edad",ylim=c(0,0.04))
lines(density(data_medicos$C2P2EDAD[data_medicos$C2P4==2]),
col=2)
legend(70,0.03,
legend=c("Hombre","Mujer"),
col=1:2,pch=15,bty = "n")
2.1.3.2.3 Función de distribución.
La función de distribución acumulada tambien llamada simplemente funcion de distribución es una función teórica que nos permite calcular probabilidades acumuladas.
Podemos estimar una función de distribución acumulada empírica a partir de los datos de la muestra utilizando la función ecdf
.
Esta función es una aproximación a la función de distribución de la población y nos permitirá calcular proporciones de casos acumulados.
# función de distribución empírica.
<- ecdf(data_medicos$C2P2EDAD) fun
Por ejemplo, podemos aplicar esta función en distintos valores e interpretarlos.
fun(24) # proporción de médicos que tienen hasta 24 años: 0.04%
## [1] 0.0004506534
fun(40) # proporción de médicos que tienen hasta 40 años: 35.3%
## [1] 0.3533123
fun(30) # proporción de médicos que tienen hasta 30 años: 7.89%
## [1] 0.07886435
Interpretación:
- La proporción de médicos que tienen hasta 24 años es 0.04%
- La proporción de médicos que tienen hasta 40 años es 35.3%
- La proporción de médicos que tienen hasta 30 años es 7.89%
Con esta función es posible reponder a la siguiente pregunta: ¿Qué proporción de médicos tienen hasta 60 años? (Ejercicio)
La función que hemos creado, puede graficarse con el comando plot:
plot(fun,
xlab="Edad",
main="Función de distribución acumulada (empírica)")
2.1.3.2.4 Gráficos de caja
En R, utilizaremos el comando “boxplot” para obtener un gráfico de cajas básico. Los gráficos de caja nos dan una vista de la distribución de una variable cuantitativa utilizando los cuartiles. Además, nos permiten identificar rapidamente la existencia de valores atípicos.
boxplot(data_medicos$C2P2EDAD)
Ejercicio: ¿Qué medidas de resumen hemos utilizado para construir la caja y los bigotes?
A continuación, verificamos los límites superior e inferior utilizados en el gráfico de cajas para la edad:
# Limites inferior(Li) y superior(Ls)
= quantile(data_medicos$C2P2EDAD,0.75) + 1.5*IQR(data_medicos$C2P2EDAD)
Ls Ls
## 75%
## 84.5
= quantile(data_medicos$C2P2EDAD,0.25) - 1.5*IQR(data_medicos$C2P2EDAD)
Li Li
## 25%
## 8.5
Observe también, que los valores atípicos son identificados a partir del uso de los límites superior (Ls) e inferior (Li).
# Valore atípicos
$C2P2EDAD[data_medicos$C2P2EDAD > Ls] data_medicos
## [1] 88 85
Con algunas líneas de código adicionales podemos personalizar este gráfico.
2.1.3.2.4.1 Personzalización.
2.1.3.2.4.1.1 Añadir un título.
boxplot(data_medicos$C2P2EDAD,
main="Boxplot para la edad"
)
2.1.3.2.4.1.2 Cambiar la orientación del gráfico.
boxplot(data_medicos$C2P2EDAD,
main="Boxplot para la edad",
horizontal=TRUE,
notch = TRUE
)
2.1.3.2.4.1.3 Cambiar el color de la caja.
# Gráfico de cajas de color celeste.
boxplot(data_medicos$C2P2EDAD,
main="Boxplot para la edad",
col="skyblue"
)
# Añade un punto que representa el promedio de los datos.
points(mean(data_medicos$C2P2EDAD),
col="red")
2.1.3.2.4.2 Comparar grupos.
Podemos utilizar los gráficos de cajas para comparar la distribución de una variable entre diferentes grupos. (En ese caso, estaríamos realizando un análisis bivariado entre una variable cuantitativa y otra cualitativa)
boxplot(C2P2EDAD~C2P4,data_medicos,
main="Boxplot para las edades por sexo"
)
Para interpretar el gráfico, utilizamos las siguiente preguntas:
- ¿Qué grupo posee mayor mediana? ¿y cuál grupo la menor mediana?
- ¿Cuál de los grupos tiene mayor dispersión?
- ¿Existen valores atípicos para cada uno de los grupos?
2.1.4 Ejercicio
- Realizar un análisis univariado para las edades de los enfermeros.
- Crear un gráfico de caja para la edades de los enfermeros. Comentar lo que se observa a partir del gráfico de caja.
- Calcular las medidas de resumen para las edades de los enfermeros e interpretarlas.
- Comparar las edades de los enfermeros por sexo con un gráfico.
- Utilizar los datos de los resultados positivos para Covid en Perú para analizar la variable edad de los contagiados. Utilizando medidas de resumen y gráficos e interpretelos.