En este último encuentro, abordaremos herramientas fundamentales del análisis estadístico básico: la construcción e interpretación de tablas de frecuencia para variables cualitativas y cuantitativas, el cálculo de medidas de resumen, y la estimación de coeficientes de asociación que nos permiten cuantificar relaciones entre variables.
Repasemos un poco lo que vimos en los encuentros anteriores:
Es una buena práctica setear el directorio de trabajo antes de
comenzar a trabajar, ya sea con la función setwd("ruta")
o
desde Session → Set Working Directory
→ Choose Directory….
setwd("~/CursoR_docentes")
Importamos los datos_excel utilizando la función
read_excel()
del paquete readxl.
, o bien desde
File → Import Dataset → From
Excel, seleccionamos el archivo y si la vista previa es
correcta damos clic en Import.
library(readxl)
datos_excel <- read_excel("datos_excel.xlsx", #Ruta del archivo
sheet = 1) #Puedo elegir una hoja específica
Cargamos los paquetes que vamos a utilizar usando la función
library()
(recordar que previamente tenemos que tener el
paquete instalado).
library(tidyverse)
library(janitor)
class(datos_excel) # para ver qué estructura tienen los datos
## [1] "tbl_df" "tbl" "data.frame"
dim(datos_excel) # para ver cuántas filas (observaciones) y columnas (variables) tiene el data set
## [1] 25 6
head(datos_excel) # para mirar los primeros registros
## # A tibble: 6 × 6
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años Ratio_Gastos
## <chr> <chr> <dbl> <dbl> <dbl>
## 1 American Century In… Capital i… 14.4 30.5 1.41
## 2 American Century Ta… Renta fija 10.7 3.34 0.49
## 3 American Century Ul… Capital n… 24.9 10.9 0.99
## 4 Artisan Small Cap Capital n… 16.9 15.7 1.18
## 5 Brown Cap Small Capital n… 35.7 15.8 1.2
## 6 DFA U.S. Micro Cap Capital n… 13.5 17.2 0.53
## # ℹ 1 more variable: Ranking_Morningstar <chr>
names(datos_excel) # para ver el nombre de las variables
## [1] "Nombre_Fondo" "Tipo_Fondo" "Activos_Netos"
## [4] "Rentabilidad_5_Años" "Ratio_Gastos" "Ranking_Morningstar"
str(datos_excel) # para obtener un resumen general de un conjunto de datos
## tibble [25 × 6] (S3: tbl_df/tbl/data.frame)
## $ Nombre_Fondo : chr [1:25] "American Century Intl. Disc" "American Century Tax-Free Bond" "American Century Ultra" "Artisan Small Cap" ...
## $ Tipo_Fondo : chr [1:25] "Capital internacional" "Renta fija" "Capital nacional" "Capital nacional" ...
## $ Activos_Netos : num [1:25] 14.4 10.7 24.9 16.9 35.7 ...
## $ Rentabilidad_5_Años: num [1:25] 30.53 3.34 10.88 15.67 15.85 ...
## $ Ratio_Gastos : num [1:25] 1.41 0.49 0.99 1.18 1.2 0.53 0.89 0.9 0.89 0.45 ...
## $ Ranking_Morningstar: chr [1:25] "3-star" "4-star" "3-star" "3-star" ...
Antes de comenzar cualquier análisis es importante, además de observar la estructura de los datos, controlar si no tenemos valores faltantes:
colSums(is.na(datos_excel))
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años
## 0 0 1 0
## Ratio_Gastos Ranking_Morningstar
## 0 0
Recordemos que algunas estrategias para el tratamiento de valores faltantes que vimos eran:
NA
.Reemplacemos el valor faltante por el promedio de la variable:
media_AN=mean(datos_excel$Activos_Netos, na.rm=T)
# Reemplazar NA por la media
datos_nvos <- datos_excel %>%
mutate(Activos_Netos = replace_na(Activos_Netos, media_AN))
#chequeamos si hay NA
colSums(is.na(datos_nvos))
## Nombre_Fondo Tipo_Fondo Activos_Netos Rentabilidad_5_Años
## 0 0 0 0
## Ratio_Gastos Ranking_Morningstar
## 0 0
dplyr
Juguemos un poco con algunas de las funciones de transformación de
datos con dplyr
que comentamos:
1- Seleccionemos las variables Tipo_Fondo y Rentabilidad_5_Años:
dos_variables <- datos_excel %>%
select(Tipo_Fondo, Rentabilidad_5_Años)
2- Transformemos la variable Tipo de Fondo en Renta Variable y Renta Fija:
dos_variables <- dos_variables %>%
mutate(Tipo_Fondo = case_when(
Tipo_Fondo == "Capital internacional" ~ "Renta variable",
Tipo_Fondo == "Capital nacional" ~ "Renta variable",
TRUE ~ Tipo_Fondo # el resto de los fondos se consideran Renta fija
))
3- Construyamos la variable categórica Rentabilidad según el siguiente esquema:
dos_variables <- dos_variables %>%
mutate(rentabilidad_cat = case_when(
Rentabilidad_5_Años <= 13.41 ~ "Poco rentable",
Rentabilidad_5_Años > 13.41 & Rentabilidad_5_Años <= 17.01 ~ "Rentable",
Rentabilidad_5_Años > 17.01 ~ "Muy rentable"
))
ggplot2
Realicemos algunos gráficos básicos:
# Gráfico de barras
ggplot(data = dos_variables, aes(x = rentabilidad_cat)) +
geom_bar() +
labs(title = "Gráfico de barra", x = "Rentabilidad categorizada", y = "Frecuencia")
# Histograma
ggplot(data = dos_variables, aes(x = Rentabilidad_5_Años)) +
geom_histogram(bins = 8, color = "white", boundary = 0) +
labs(title = "Histograma", x = "Rentabilidad de los últimos 5 años", y = "Frecuencia")
# Boxplot
ggplot(data = dos_variables, aes(y = Rentabilidad_5_Años, x=Tipo_Fondo)) +
geom_boxplot() +
labs(title = "Boxplot", x = "", y = "Rentabilidad de los últimos 5 años")
Las tablas de frecuencia permiten organizar y resumir datos tanto de variables cualitativas como cuantitativas.
Podemos construir la frecuencia absoluta usando la función
count()
:
tabla_RM <- datos_excel %>%
count(Ranking_Morningstar) %>% # para contar
rename(Frecuencia=n) %>% # para renombrar la variable "n" que hicimos en la capa anterior
adorn_totals() # para agregarle el Total
tabla_RM
## Ranking_Morningstar Frecuencia
## 2-star 1
## 3-star 12
## 4-star 10
## 5-star 2
## Total 25
Podemos agregarle la frecuencia relativa porcentual:
tabla_RM <- datos_excel %>%
count(Ranking_Morningstar) %>% # para contar
rename(Frecuencia=n) %>% # para renombrar la variable "n" que hicimos en la capa anterior
mutate(`Frecuencia porcentual`=round(Frecuencia/sum(Frecuencia)*100)) %>% # para calcular la frecuencia relativa porcentual
adorn_totals() # para agregarle el Total
tabla_RM
## Ranking_Morningstar Frecuencia Frecuencia porcentual
## 2-star 1 4
## 3-star 12 48
## 4-star 10 40
## 5-star 2 8
## Total 25 100
En el caso de las variables cuantitativas discretas, en general podemos repetir el procedimiento visto para las variables cualitativas: contar cuántas veces aparece cada uno de sus posibles valores en nuestros datos. Pero cuando la variable es cuantitativa continua, debemos primero armar intervalos para agrupar los distintos valores.
Esto lo hacemos con la función cut()
, en la cual ponemos
como argumento la variable a categorizar y la cantidad de intervalos o
categorías, y categoriza la variable según la cantidad de puntos de
cortes que le ingresamos.
Si bien hay varias fórmulas para calcular la cantidad de intervalos a
construir para la distribución de una variable cuantitativa continua,
una muy conocida es la de Sturges. En R
podemos usar la
función nclass.Sturges()
para aplicar esa fórmula y obtener
cuántos intervalos debería haber.
cant_clases=nclass.Sturges(datos_excel$Rentabilidad_5_Años)
cant_clases
## [1] 6
tabla_Rent <- datos_excel %>%
mutate(intervalo = cut(Rentabilidad_5_Años, cant_clases)) %>%
count(intervalo, .drop = FALSE) %>% # el argumento .drop = FALSE permite conservar los intervalos aunque tengan frecuencia 0
rename(Frecuencia = n) %>%
mutate(`Frecuencia porcentual`=round(Frecuencia/sum(Frecuencia)*100)) %>%
adorn_totals()
tabla_Rent
## intervalo Frecuencia Frecuencia porcentual
## (2.32,10.5] 5 20
## (10.5,18.6] 15 60
## (18.6,26.7] 2 8
## (26.7,34.9] 2 8
## (34.9,43] 0 0
## (43,51.1] 1 4
## Total 25 100
Las tablas de doble entrada o tablas de contingencia permiten resumir
la relación entre dos variables cualitativas. Se pueden construir
fácilmente con la función tabyl()
, indicando como
argumentos las dos variables: la primera se organiza por filas y la
segunda por columnas.
tabla_dos <- dos_variables %>%
tabyl(Tipo_Fondo , rentabilidad_cat) %>%
adorn_totals("both") # con el argumento "both" agrega totales por filas y por columnas
tabla_dos
## Tipo_Fondo Muy rentable Poco rentable Rentable Total
## Renta fija 0 4 1 5
## Renta variable 7 3 10 20
## Total 7 7 11 25
Las medidas de resumen describen características centrales y de dispersión de las variables numéricas.
dos_variables %>%
summarise(
media = mean(Rentabilidad_5_Años),
mediana = median(Rentabilidad_5_Años),
desv_std = sd(Rentabilidad_5_Años),
min = min(Rentabilidad_5_Años),
max = max(Rentabilidad_5_Años),
Q1 = quantile(Rentabilidad_5_Años, 0.25),
Q3 = quantile(Rentabilidad_5_Años, 0.75)
)
## # A tibble: 1 × 7
## media mediana desv_std min max Q1 Q3
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 16.5 15.5 10.4 2.37 51.1 13.4 17.2
Desagregadas por Tipo de Fondo:
dos_variables %>%
group_by(Tipo_Fondo) %>%
summarise(media = mean(Rentabilidad_5_Años),
mediana = median(Rentabilidad_5_Años),
desv = sd(Rentabilidad_5_Años),
n = n())
## # A tibble: 2 × 5
## Tipo_Fondo media mediana desv n
## <chr> <dbl> <dbl> <dbl> <int>
## 1 Renta fija 5.27 3.34 4.70 5
## 2 Renta variable 19.3 16.3 9.50 20
Las medidas de asociación permiten cuantificar el grado de relación entre dos variables. El tipo de medida a utilizar depende del tipo de variables involucradas. En la tabla que sigue presentamos las más utilizadas:
Tipo de variable | Medida |
Función en R
|
Uso |
---|---|---|---|
Dos cuantitativas | Coeficiente de correlación de Pearson |
cor(x, y, method = 'pearson')
|
Su valor varía entre -1 y 1. |
Dos cualitativas nominales | Coeficiente V de Cramer |
DescTools::CramerV(tabla)
|
Su valor varía entre 0 y 1. |
Dos cualitativas ordinales | Coeficiente de correlación de Spearman |
cor(x, y, method = 'spearman')
|
Su valor varía entre -1 y 1. |
Calculemos algunas para nuestras variables:
cor(datos_excel$Rentabilidad_5_Años, datos_excel$Ratio_Gastos, method = "pearson")
## [1] 0.4926285
# Usamos la función CramerV del paquete DescTools sin cargar todo el paquete con library(). Igualmente primero debe instalarse el paquete!
DescTools::CramerV(table(dos_variables$Tipo_Fondo, dos_variables$rentabilidad_cat))
## [1] 0.586648
Para cerrar el curso trabajemos con alguna de las bases de la
Encuesta Permanente de Hogares. Carguemos el paquete eph
e
importemos la base de datos individual del 4to trimestre de 2024:
library(eph)
base <- get_microdata(year = 2024, trimester = 4, type='individual', vars ="all")
Miremos la dimensión y el nombre de las variables:
dim(base)
## [1] 46860 235
names(base)
## [1] "CODUSU" "ANO4" "TRIMESTRE" "NRO_HOGAR" "COMPONENTE"
## [6] "H15" "REGION" "MAS_500" "AGLOMERADO" "PONDERA"
## [11] "CH03" "CH04" "CH05" "CH06" "CH07"
## [16] "CH08" "CH09" "CH10" "CH11" "CH12"
## [21] "CH13" "CH14" "CH15" "CH15_COD" "CH16"
## [26] "CH16_COD" "NIVEL_ED" "ESTADO" "CAT_OCUP" "CAT_INAC"
## [31] "IMPUTA" "PP02C1" "PP02C2" "PP02C3" "PP02C4"
## [36] "PP02C5" "PP02C6" "PP02C7" "PP02C8" "PP02E"
## [41] "PP02H" "PP02I" "PP03C" "PP03D" "PP3E_TOT"
## [46] "PP3F_TOT" "PP03G" "PP03H" "PP03I" "PP03J"
## [51] "INTENSI" "PP04A" "PP04B_COD" "PP04B1" "PP04B2"
## [56] "PP04B3_MES" "PP04B3_ANO" "PP04B3_DIA" "PP04C" "PP04C99"
## [61] "PP04D_COD" "PP04G" "PP05B2_MES" "PP05B2_ANO" "PP05B2_DIA"
## [66] "PP05C_1" "PP05C_2" "PP05C_3" "PP05E" "PP05F"
## [71] "PP05H" "PP06A" "PP06C" "PP06D" "PP06E"
## [76] "PP06H" "PP07A" "PP07C" "PP07D" "PP07E"
## [81] "PP07F1" "PP07F2" "PP07F3" "PP07F4" "PP07F5"
## [86] "PP07G1" "PP07G2" "PP07G3" "PP07G4" "PP07G_59"
## [91] "PP07H" "PP07I" "PP07J" "PP07K" "PP08D1"
## [96] "PP08D4" "PP08F1" "PP08F2" "PP08J1" "PP08J2"
## [101] "PP08J3" "PP09A" "PP09A_ESP" "PP09B" "PP09C"
## [106] "PP09C_ESP" "PP10A" "PP10C" "PP10D" "PP10E"
## [111] "PP11A" "PP11B_COD" "PP11B1" "PP11B2_MES" "PP11B2_ANO"
## [116] "PP11B2_DIA" "PP11C" "PP11C99" "PP11D_COD" "PP11G_ANO"
## [121] "PP11G_MES" "PP11G_DIA" "PP11L" "PP11L1" "PP11M"
## [126] "PP11N" "PP11O" "PP11P" "PP11Q" "PP11R"
## [131] "PP11S" "PP11T" "P21" "DECOCUR" "IDECOCUR"
## [136] "RDECOCUR" "GDECOCUR" "PDECOCUR" "ADECOCUR" "PONDIIO"
## [141] "TOT_P12" "P47T" "DECINDR" "IDECINDR" "RDECINDR"
## [146] "GDECINDR" "PDECINDR" "ADECINDR" "PONDII" "V3_M"
## [151] "V4_M" "V8_M" "V9_M" "V10_M" "V12_M"
## [156] "V18_M" "V19_AM" "T_VI" "ITF" "DECIFR"
## [161] "IDECIFR" "RDECIFR" "GDECIFR" "PDECIFR" "ADECIFR"
## [166] "IPCF" "DECCFR" "IDECCFR" "RDECCFR" "GDECCFR"
## [171] "PDECCFR" "ADECCFR" "PONDIH" "V2_02_M" "V2_03_M"
## [176] "V5_03_M" "V11_02_M" "PP07B1_01" "EMPLEO" "SECTOR"
## [181] "PP02A" "PP02B" "PP02D" "PP02F" "PP02G"
## [186] "PP03K" "PP04A1" "PP05B3" "PP05I" "PP05J"
## [191] "PP05K" "PP06E1" "PP06K" "PP06K_SEM" "PP06K_MES"
## [196] "PP06L" "PP07F1_1" "PP07F1_2" "PP07F1_3" "PP07I2"
## [201] "PP07I3" "PP07I4" "PP07L" "PP07M" "PP08G"
## [206] "PP08G_DSEM" "PP08G_DMES" "PP08H" "PP10B1" "PP10B2"
## [211] "PP10B3" "PP10B4" "PP10B5" "PP10B6" "PP10B7"
## [216] "PP10B8" "PP10B9" "PP10B10" "PP11L2" "V2_01_M"
## [221] "V5_01_M" "V5_02_M" "V11_01_M" "V21_01_M" "V21_02_M"
## [226] "V21_03_M" "V22_01_M" "V22_02_M" "V22_03_M" "P_DECCF"
## [231] "P_RDECCF" "P_GDECCF" "P_PDECCF" "P_IDECCF" "P_ADECCF"
Para ver qué mide cada una podemos consultar el Diseño de registros y estructura para las bases preliminares Hogar y Personas.
Vamos a trabajar con los datos del aglomerado Gran Paraná. Para ello debemos filtrar el AGLOMERADO 6:
parana <- base %>%
filter(AGLOMERADO==6)
Trabajemos con la variable sexo (CH04) y edad (CH06). Realicemos las transformaciones necesarias y construyamos tablas, gráficos y medidas de resumen:
# Recodificamos sexo y la renombramos
parana <- parana %>%
mutate(CH04=case_when( CH04 == 1 ~ "Varon",
CH04 == 2 ~ "Mujer")) %>%
rename(Sexo=CH04)
# Chequeamos si hay valores faltantes en sexo
sum(is.na(parana$Sexo))
## [1] 0
# Gráfico de barras
ggplot(parana, aes(x=Sexo, fill=Sexo))+
geom_bar()
# Tabla de frecuencias
tabla_sexo <- parana %>%
count(Sexo) %>%
rename(Frecuencia=n) %>%
mutate(`Frecuencia porcentual`=round(Frecuencia/sum(Frecuencia)*100)) %>%
adorn_totals()
tabla_sexo
## Sexo Frecuencia Frecuencia porcentual
## Mujer 752 53
## Varon 674 47
## Total 1426 100
# Renombrarmos edad
parana <- parana %>%
rename(Edad=CH06)
# Chequeamos si hay valores faltantes en edad
sum(is.na(parana$Edad))
## [1] 0
# Para ver en cuántos intervalos deberíamos categorizarla
cant_int_edad = nclass.Sturges(parana$Edad)
cant_int_edad
## [1] 12
# Gráficos: histograma y boxplot
ggplot(parana, aes(x=Edad))+
geom_histogram(bins=12, col="white")
ggplot(parana, aes(x=Edad))+
geom_boxplot()
# Tabla de frecuencias
tabla_Edad <- parana %>%
mutate(intervalos=cut(Edad, cant_int_edad)) %>%
count(intervalos) %>%
rename(Frecuencia=n) %>%
mutate(`Frecuencia porcentual`=round(Frecuencia/sum(Frecuencia)*100)) %>%
adorn_totals()
tabla_Edad
## intervalos Frecuencia Frecuencia porcentual
## (-1.1,7] 117 8
## (7,15] 179 13
## (15,23] 163 11
## (23,31] 174 12
## (31,39] 146 10
## (39,47] 159 11
## (47,55] 130 9
## (55,63] 113 8
## (63,71] 116 8
## (71,79] 81 6
## (79,87] 37 3
## (87,95.1] 11 1
## Total 1426 100
# Medidas de resumen
medidas <- parana %>%
summarise(Media=mean(Edad),
Mediana=median(Edad),
Desvio=sd(Edad),
Minimo=min(Edad),
Maximo=max(Edad))
medidas
## # A tibble: 1 × 5
## Media Mediana Desvio Minimo Maximo
## <dbl> <dbl> <dbl> <int> <int>
## 1 38.0 36 22.8 -1 95
# Análisis de la edad según sexo
# Gráficos
ggplot(parana, aes(x=Edad, fill=Sexo))+
geom_histogram(bins=12, col="white")+
facet_grid(~Sexo)
ggplot(parana, aes(x=Sexo, y=Edad, fill=Sexo))+
geom_boxplot()
# Medidas de resumen
medidas_porSexo <- parana %>%
group_by(Sexo) %>%
summarise(Media=mean(Edad),
Mediana=median(Edad),
Desvio=sd(Edad),
Minimo=min(Edad),
Maximo=max(Edad))
medidas_porSexo
## # A tibble: 2 × 6
## Sexo Media Mediana Desvio Minimo Maximo
## <chr> <dbl> <dbl> <dbl> <int> <int>
## 1 Mujer 39.9 38 23.2 -1 95
## 2 Varon 35.8 33.5 22.3 -1 88