Trabajar con proyectos en RStudio hace que todo el trabajo sea más sencillo. Los proyectos crean una carpeta en nuestra PC en donde se almacenarán los archivos, tablas, scripts, y hace que todo sea más organizado.
Trabajar con proyectos en RStudio hace que todo el trabajo sea más sencillo. Los proyectos crean una carpeta en nuestra PC en donde se almacenarán los archivos, tablas, scripts, y hace que todo sea más organizado.
Para crear un proyecto tenés podés entrar en:
Y luego poner el nombre de la carpeta.
Cuando hacemos algún tutorial, los datos están perfectos, limpios, y prolijos. Y cuando querés aplicar el mismo código a tus propios datos, resulta que no funciona, o tenés que hacer mucho procesamiento de datos para terminar replicando un ejemplo de un tutorial.
Cuando hacemos algún tutorial, los datos están perfectos, limpios, y prolijos. Y cuando querés aplicar el mismo código a tus propios datos, resulta que no funciona, o tenés que hacer mucho procesamiento de datos para terminar replicando un ejemplo de un tutorial.
Por estas razones, la limpieza de datos, suele representar entre el 60 al 80% de cualquier proyecto de Analytics, hasta lograr tener datos ordenados (tidy data). Entre algunos principios de tidy data podemos mencionar dos:
Cuando hacemos algún tutorial, los datos están perfectos, limpios, y prolijos. Y cuando querés aplicar el mismo código a tus propios datos, resulta que no funciona, o tenés que hacer mucho procesamiento de datos para terminar replicando un ejemplo de un tutorial.
Por estas razones, la limpieza de datos, suele representar entre el 60 al 80% de cualquier proyecto de Analytics, hasta lograr tener datos ordenados (tidy data). Entre algunos principios de tidy data podemos mencionar dos:
El paquete dplyr es uno de los paquetes embebidos dentro del paquete tidyverse: un conjunto de paquetes destinados a la limpieza y manipulación de datos y que se convirtió en un estándar en la práctica de la limpieza y manipulación de datos en R. dplyr
fue desarrollado por Hadley Wickham, Romain François, Lionel Henry y Kirill Müller.
Una de las razones por las que se hizo tan popular es por su sintaxis simple, con nombres de funciones que usan palabras muy coloquiales, imitando la forma en la que hablamos.
Usualmente se dice que usamos dplyr
para hacer data wrangling. Así que empecemos a aprender a domar nuestros datos.
Al igual que la gran mayoría de los paquetes de R, podemos instalar el paquete directamente desde el script:
# Instalando el paquete individualinstall.packages("dplyr")# Instalando el conjunto de paquetes de tidyverseinstall.packages("tidyverse")
Al igual que la gran mayoría de los paquetes de R, podemos instalar el paquete directamente desde el script:
# Instalando el paquete individualinstall.packages("dplyr")# Instalando el conjunto de paquetes de tidyverseinstall.packages("tidyverse")
Antes de empezar a usar las funciones de dplyr, tenemos que cargarlo con la función library()
:
library(dplyr)
Al igual que la gran mayoría de los paquetes de R, podemos instalar el paquete directamente desde el script:
# Instalando el paquete individualinstall.packages("dplyr")# Instalando el conjunto de paquetes de tidyverseinstall.packages("tidyverse")
Antes de empezar a usar las funciones de dplyr, tenemos que cargarlo con la función library()
:
library(dplyr)
Ahora si...
Los cheatsheet son documentos con resúmenes de las principales funciones de los paquetes más utilizados.
La comunidad de R de hispanoamérica ha traducido unos cuantos, gracias a quienes podemos contar hoy con un cheatsheet en castellano.
Vamos a utilizar una versión abreviada de la 🥝 Encuesta KIWI de Sueldos de RH que desarrollamos con el Club de R para RRHH (pueden ver los resultados en este link).
library(dplyr) # Manipulación y limpieza de datoslibrary(readr) # Lectura y carga de archivos# Cargamos encuesta de sueldosencuesta <- read_delim("https://raw.githubusercontent.com/r4hr/r4hr_introduccion_dplyr/main/Datos/encuesta_sueldos.csv", delim = ",")
Vamos a explorar algunas características del dataset:
glimpse(encuesta)
## Rows: 464## Columns: 15## $ genero <chr> "Femenino", "Femenino", "Masculino", "Femenino", "Fem~## $ edad <dbl> 31, 28, 25, 33, 24, 30, 39, 23, 29, 30, 32, 28, 25, 2~## $ universidad <chr> "Universidad Privada", "Universidad Privada", "Univer~## $ rubro <chr> "Función pública", "Alimentación; bebidas; tabaco", "~## $ empleados <dbl> 400, 150, 186, 4, 80, 135, 15, 10000, 300, 65, 10000,~## $ origen_capital <chr> "Nacional", "Nacional", "Nacional", "Nacional", "Naci~## $ empleados_rh <dbl> 6, 3, 2, 1, 1, 3, 1, 40, 2, 3, 10, 15, 2, 2, 2, 2, 6,~## $ puesto <chr> "Administrativo", "Administrativo", "Administrativo",~## $ personas_a_cargo <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,~## $ anios_rh <dbl> 8, 9, 2, 3, 1, 6, 6, 3, 5, 6, 5, 8, 2, 1, 1, 4, 5, 18~## $ sueldo_bruto <dbl> 41000.00, 40000.00, 43954.43, 40000.00, 15000.00, 570~## $ aumento <dbl> 0.0, 10.0, 0.0, 20.0, 0.0, 0.0, 49.0, 0.0, 0.0, 30.0,~## $ erp <chr> "No tenemos sistema de gestión", "Tango", "Tango", "E~## $ satisfaccion <dbl> 2, 4, 3, 3, 2, 3, 4, 3, NA, NA, 4, 3, 3, 4, 4, 1, 3, ~## $ buscando_trabajo <chr> "No, pero escucho ofertas", "No, pero escucho ofert~
Una de las razones por las cuales tidyverse se hizo tan popular es que la lógica de las funciones imita el razonamiento que haríamos verbalmente.
Una de las razones por las cuales tidyverse se hizo tan popular es que la lógica de las funciones imita el razonamiento que haríamos verbalmente.
Por ejemplo, ¿cómo harían para calcular el sueldo promedio por puesto y ordenar los resultados de mayor a menor?
Una de las razones por las cuales tidyverse se hizo tan popular es que la lógica de las funciones imita el razonamiento que haríamos verbalmente.
Por ejemplo, ¿cómo harían para calcular el sueldo promedio por puesto y ordenar los resultados de mayor a menor?
encuesta %>% select(puesto, sueldo_bruto) %>% # Selecciona las columnas group_by(puesto) %>% # Agrupa por la variable puesto summarise(sueldo_promedio = mean(sueldo_bruto)) %>% # Crea una variable con el sueldo promedio arrange(-sueldo_promedio) # Ordena descendentemente los resultados por la variable que pasemos.
## # A tibble: 7 x 2## puesto sueldo_promedio## <chr> <dbl>## 1 Gerente 230972.## 2 Director 210788.## 3 Jefe 110486.## 4 HRBP 93805.## 5 Responsable 75024.## 6 Analista 68061.## 7 Administrativo 44154.
¿Vieron este símbolo %>%
en la slide anterior? En la jerga lo conocemos como "pipe" (atajo de teclado Ctrl + Mayús + M). Lo que nos permite este "tubo" es ordenar el código en secuencias, haciéndolo más comprensible a la lectura.
Una de las ventajas del pipe es que no necesitamos invocar al dataframe en cada función que encadenamos en el pipe.
Por ejemplo, si quiero ver los sueldos brutos por puesto de las personas que no tienen gente a cargo ordenados por el puesto. Los pasos son:
puesto
, sueldo_bruto
, personas_a_cargo
.personas_a_cargo
los casos que no tienen gente a cargo.Acá estoy usando la función
head()
para que quede prolijo en la presentación. Ustedes no la usen y recuerden sacar el último paréntesis
head(arrange(filter(select(encuesta, puesto, sueldo_bruto, personas_a_cargo), personas_a_cargo > 0), puesto))
## # A tibble: 6 x 3## puesto sueldo_bruto personas_a_cargo## <chr> <dbl> <dbl>## 1 Administrativo 94050 4## 2 Analista 650000 70## 3 Analista 37000 44## 4 Analista 65500 2## 5 Analista 45500 120## 6 Analista 134000 2
Esto mismo usando el pipe de dplyr lo hacemos así:
encuesta %>% select(puesto, sueldo_bruto, personas_a_cargo) %>% filter(personas_a_cargo>0) %>% arrange(puesto) %>% head()
## # A tibble: 6 x 3## puesto sueldo_bruto personas_a_cargo## <chr> <dbl> <dbl>## 1 Administrativo 94050 4## 2 Analista 650000 70## 3 Analista 37000 44## 4 Analista 65500 2## 5 Analista 45500 120## 6 Analista 134000 2
arrange(filter(select(encuesta, puesto, sueldo_bruto, personas_a_cargo), personas_a_cargo > 0), puesto)
encuesta %>% select(puesto, sueldo_bruto, personas_a_cargo) %>% filter(personas_a_cargo>0) %>% arrange(puesto)
En esta presentación vamos a repasar los siguientes "verbos" o funciones:
Hay muchas funciones más, que pueden explorar en el cheatsheet.
La función select()
sirve para elegir las columnas (variables) con las que queremos trabajar. También nos permite traer las columnas en el orden que las necesitemos.
encuesta %>% select(satisfaccion, sueldo_bruto) %>% head()
## # A tibble: 6 x 2## satisfaccion sueldo_bruto## <dbl> <dbl>## 1 2 41000 ## 2 4 40000 ## 3 3 43954.## 4 3 40000 ## 5 2 15000 ## 6 3 57000
select()
tiene algunas variantes interesantes (y en general aplican para casi todas las funciones de dplyr).
Supongamos que quiera seleccionar todas las columnas numéricas nada más:
encuesta %>% select_if(is.numeric) %>% head()
## # A tibble: 6 x 8## edad empleados empleados_rh personas_a_cargo anios_rh sueldo_bruto aumento## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>## 1 31 400 6 0 8 41000 0## 2 28 150 3 0 9 40000 10## 3 25 186 2 0 2 43954. 0## 4 33 4 1 0 3 40000 20## 5 24 80 1 0 1 15000 0## 6 30 135 3 0 6 57000 0## # ... with 1 more variable: satisfaccion <dbl>
filter()
nos permite obtener las filas (observaciones) que cumplen con las condiciones que necesitamos.
Ej.: Respuestas de Universidades Públicas
encuesta %>% # Prestar atención al doble signo igual "==" filter(universidad == "Universidad Pública") %>% head()
## # A tibble: 6 x 15## genero edad universidad rubro empleados origen_capital empleados_rh puesto## <chr> <dbl> <chr> <chr> <dbl> <chr> <dbl> <chr> ## 1 Femeni~ 25 Universida~ Transp~ 22000 Nacional 2 Admin~## 2 Femeni~ 24 Universida~ Comerc~ 94 Nacional 2 Admin~## 3 Femeni~ 24 Universida~ Comerc~ 94 Nacional 2 Admin~## 4 Femeni~ 33 Universida~ Servic~ 117 Nacional 2 Admin~## 5 Femeni~ 29 Universida~ Petról~ 225 Multinacional 6 Admin~## 6 Mascul~ 46 Universida~ Constr~ 250 Nacional 2 Admin~## # ... with 7 more variables: personas_a_cargo <dbl>, anios_rh <dbl>,## # sueldo_bruto <dbl>, aumento <dbl>, erp <chr>, satisfaccion <dbl>,## # buscando_trabajo <chr>
filter()
nos permite obtener las filas (observaciones) que cumplen con las condiciones que necesitamos.
Ej.: Respuestas de trabajadores privados (filtrar todo lo que no sea Función pública
)
encuesta %>% # Prestar atención al signo "No igual a "!=" filter(universidad != "Función pública") %>% head()
## # A tibble: 6 x 15## genero edad universidad rubro empleados origen_capital empleados_rh puesto## <chr> <dbl> <chr> <chr> <dbl> <chr> <dbl> <chr> ## 1 Femeni~ 31 Universidad~ Funci~ 400 Nacional 6 Admin~## 2 Femeni~ 28 Universidad~ Alime~ 150 Nacional 3 Admin~## 3 Mascul~ 25 Universidad~ Miner~ 186 Nacional 2 Admin~## 4 Femeni~ 33 Universidad~ Servi~ 4 Nacional 1 Admin~## 5 Femeni~ 24 Universidad~ Const~ 80 Nacional 1 Admin~## 6 Femeni~ 30 Universidad~ Servi~ 135 Nacional 3 Admin~## # ... with 7 more variables: personas_a_cargo <dbl>, anios_rh <dbl>,## # sueldo_bruto <dbl>, aumento <dbl>, erp <chr>, satisfaccion <dbl>,## # buscando_trabajo <chr>
Estas son los operadores lógicos que nos van a ayudar con la función filter.
filter()
nos permite obtener las filas (observaciones) que cumplen con las condiciones que necesitamos.
Ej.: Listado de respuestas de Universidad Privada y de empresas con más de 700 empleados.
# Filtramos los empleados que son de Universidad Privada y de empresas con más de 700 empleados.encuesta %>% filter(universidad == "Universidad Privada" & empleados > 700) %>% head()
## # A tibble: 6 x 15## genero edad universidad rubro empleados origen_capital empleados_rh puesto## <chr> <dbl> <chr> <chr> <dbl> <chr> <dbl> <chr> ## 1 Femeni~ 23 Universida~ Alimen~ 10000 Nacional 40 Admin~## 2 Femeni~ 32 Universida~ Servic~ 10000 Multinacional 10 Admin~## 3 Femeni~ 35 Universida~ Comerc~ 1433 Nacional 10 Anali~## 4 Femeni~ 41 Universida~ Transp~ 1000 Nacional 8 Anali~## 5 Femeni~ 27 Universida~ Produc~ 5350 Multinacional 160 Anali~## 6 Femeni~ 31 Universida~ Petról~ 60000 Multinacional 2500 Anali~## # ... with 7 more variables: personas_a_cargo <dbl>, anios_rh <dbl>,## # sueldo_bruto <dbl>, aumento <dbl>, erp <chr>, satisfaccion <dbl>,## # buscando_trabajo <chr>
Veamos la distribución de los sueldos con un histograma
library(ggplot2) ggplot(encuesta, aes(x = sueldo_bruto)) + # Defino fuente de datos y variable a graficar geom_histogram() + # Tipo de gráfico ggtitle("Distribución de sueldos brutos") # Agrego título al gráfico
😱
¿Qué salió mal? Tenemos valores extremos que pueden ser válidos, pero que no son representativos. Exploremos la variable:
summary(encuesta$sueldo_bruto)
## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 2 53837 74000 94370 105250 2140000
¿Qué salió mal? Tenemos valores extremos que pueden ser válidos, pero que no son representativos. Exploremos la variable:
summary(encuesta$sueldo_bruto)
## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 2 53837 74000 94370 105250 2140000
Vemos que hay sueldos muy altos, que pueden ser válidos pero que son atípicos. Y también encontramos sueldos muy bajos.
Podemos filtrar un rango de una variable numérica de la siguiente manera combinando la función between()
:
# Creo un objeto nuevoencuesta_limpia <- encuesta %>% filter(between(sueldo_bruto, # Variable a filtrar 50000, # Valor mínimo 200000)) # Valor máximo# Vuelvo a graficarggplot(encuesta_limpia, aes(x = sueldo_bruto)) + geom_histogram() + ggtitle("Distribución de sueldos brutos")
👍
filter()
nos permite obtener las filas (observaciones) que cumplen con las condiciones que necesitamos.
Ej.: Empleados de dos rubros diferentes
encuesta %>% filter(rubro == "Comercio"| rubro == "Servicios de salud") %>% head()
## # A tibble: 6 x 15## genero edad universidad rubro empleados origen_capital empleados_rh puesto## <chr> <dbl> <chr> <chr> <dbl> <chr> <dbl> <chr> ## 1 Femeni~ 30 Universidad~ Servi~ 135 Nacional 3 Admin~## 2 Femeni~ 30 Universidad~ Servi~ 65 Nacional 3 Admin~## 3 Femeni~ 24 Universidad~ Comer~ 94 Nacional 2 Admin~## 4 Femeni~ 24 Universidad~ Comer~ 94 Nacional 2 Admin~## 5 Femeni~ 33 Universidad~ Servi~ 117 Nacional 2 Admin~## 6 Femeni~ 24 Universidad~ Comer~ 94 Nacional 2 Admin~## # ... with 7 more variables: personas_a_cargo <dbl>, anios_rh <dbl>,## # sueldo_bruto <dbl>, aumento <dbl>, erp <chr>, satisfaccion <dbl>,## # buscando_trabajo <chr>
Una alternativa es usar un vector de selección
encuesta %>% filter(rubro %in% c("Comercio", "Servicios de salud"))
group_by()
es una función para agrupar las variables en función de los valores de una o varias columnas.
Por ejemplo si quiero ver los sueldos promedio por puesto, tengo que agrupar por puesto, y luego calculo el promedio.
Para calcular el promedio voy a necesitar la función summarise()
, que crea nuevas columnas con medidas de resumen estadístico.
encuesta %>% select(puesto, sueldo_bruto) %>% # Agrupo por puesto group_by(puesto) %>% #Calculo el sueldo promedio summarise(sueldo_promedio = mean(sueldo_bruto))
## # A tibble: 7 x 2## puesto sueldo_promedio## * <chr> <dbl>## 1 Administrativo 44154.## 2 Analista 68061.## 3 Director 210788.## 4 Gerente 230972.## 5 HRBP 93805.## 6 Jefe 110486.## 7 Responsable 75024.
]
mutate()
tiene dos usos principales.
Crear nuevas columnas en base a las columnas que ya existen en el dataset. Por ejemplo, para calcular un sueldo anual de una columna de sueldo mensual.
Para modificar las características de una variable. Por ejemplo, para cambiar el tipo de variable, como pasar una variable numérica a tipo factor
o definir el orden de una variable.
Calcular el sueldo anual en base a la columna sueldo bruto
En Argentina tenemos un bono anual llamado aguinaldo, que equivale a un sueldo más y se paga dos veces en el año.
encuesta %>% select(puesto, sueldo_bruto) %>% mutate(sueldo_bruto_anual = sueldo_bruto * 13) %>% head()
## # A tibble: 6 x 3## puesto sueldo_bruto sueldo_bruto_anual## <chr> <dbl> <dbl>## 1 Administrativo 41000 533000 ## 2 Administrativo 40000 520000 ## 3 Administrativo 43954. 571408.## 4 Administrativo 40000 520000 ## 5 Administrativo 15000 195000 ## 6 Administrativo 57000 741000
Con mutate podemos cambiar las características de algunas variables. Por ejemplo, la variable puesto
es de tipo character
o nominal, es decir que no nos permite ordenar sus resultados.
class(encuesta$puesto)
## [1] "character"
Si convertimos esta variable en tipo factor
podremos definir el orden que nos sirva para representar la jerarquía.
encuesta %>% select(puesto, sueldo_bruto) %>% mutate(puesto = factor(puesto, levels = c("Director", "Gerente", "Jefe", "Responsable", "HRBP", "Analista", "Administrativo"))) %>% group_by(puesto) %>% summarise(sueldo_promedio = mean(sueldo_bruto))
## # A tibble: 7 x 2## puesto sueldo_promedio## * <fct> <dbl>## 1 Director 210788.## 2 Gerente 230972.## 3 Jefe 110486.## 4 Responsable 75024.## 5 HRBP 93805.## 6 Analista 68061.## 7 Administrativo 44154.
La función case_when
la podemos usar dentro de mutate para crear categorías a partir de variables numéricas.
Usemos esto para crear rangos de empleados, y calcular el sueldo promedio después.
encuesta <- encuesta %>% mutate(cantidad_empleados = case_when( empleados <= 100 ~ "Hasta 100", empleados <= 500 ~ "Hasta 500", empleados <= 1000 ~ "Hasta 1000", empleados <= 5000 ~ "Hasta 5000", empleados = TRUE ~ "Más de 5000" )) encuesta %>% group_by(cantidad_empleados) %>% summarise(sueldo_promedio = mean(sueldo_bruto))
## # A tibble: 5 x 2## cantidad_empleados sueldo_promedio## * <chr> <dbl>## 1 Hasta 100 84486.## 2 Hasta 1000 88247.## 3 Hasta 500 103045.## 4 Hasta 5000 94464.## 5 Más de 5000 92847.
Realicemos un análisis de los sueldos brutos por cantidad de empleados, según el origen del capital.
Pasos:
origen_capital
y la columna nueva de cantidad_empleados
.summarise()
# Creo un objeto nuevoanalisis_sueldos <- encuesta %>% # Agrupo por origen_capital y cantidad_empleados group_by(origen_capital, cantidad_empleados) %>% # Calculo el sueldo promedio summarise(sueldo_promedio = mean(sueldo_bruto))# Veo los resultadosanalisis_sueldos
## # A tibble: 10 x 3## # Groups: origen_capital [2]## origen_capital cantidad_empleados sueldo_promedio## <chr> <chr> <dbl>## 1 Multinacional Hasta 100 179451.## 2 Multinacional Hasta 1000 104350 ## 3 Multinacional Hasta 500 130732.## 4 Multinacional Hasta 5000 102300.## 5 Multinacional Más de 5000 96458.## 6 Nacional Hasta 100 67464.## 7 Nacional Hasta 1000 84566.## 8 Nacional Hasta 500 91306.## 9 Nacional Hasta 5000 88162.## 10 Nacional Más de 5000 90714.
ggplot(analisis_sueldos, aes(x = cantidad_empleados, y = sueldo_promedio, fill = origen_capital)) + # Color de las barras geom_col(position = "dodge") # Posiciona las barras una al lado de la otra
library(scales) # Modificar formato escalas gráficolibrary(ggthemes) # Añade más opciones de formato a los gráficosggplot(analisis_sueldos, aes(x = cantidad_empleados, y = sueldo_promedio, fill = origen_capital)) + # Color de las barras geom_col(position = "dodge") + scale_fill_economist() + # Cambia paleta de colores de las barras. # Añade separador de miles al eje y scale_y_continuous(labels = comma_format(big.mark = ".", decimal.mark = ",")) + labs(title = "Sueldo Promedio por Origen de Capital \n y Tamaño de Empresa", #Título subtitle = "En Pesos Argentinos", #Subtítulo x = "", y ="", # Elimino etiquetas de eje fill = "Origen de Capital", # Cambio nombre colores caption = "HR Bootcamp - Humanos Reales \n Fuente: Encuesta KIWI de Sueldos de RH") + # Agrega nota al pie theme_economist() # Modifica el estilo del gráfico
Ciencia de Datos para Gente Sociable de Antonio Vazquez Brust
R para Ciencia de Datos de Hadley Wickham y Garrett Grolemund
Si te gustó esta sesión me pueden encontrar en:
Recuerden compartir sus capturas de pantalla y sensaciones con los hashtags:
Presentación realizada con el paquete Xaringan desarrollado por Yihui Xie.
Gracias a Patricia Loto por compartir el tutorial
Keyboard shortcuts
↑, ←, Pg Up, k | Go to previous slide |
↓, →, Pg Dn, Space, j | Go to next slide |
Home | Go to first slide |
End | Go to last slide |
Number + Return | Go to specific slide |
b / m / f | Toggle blackout / mirrored / fullscreen mode |
c | Clone slideshow |
p | Toggle presenter mode |
t | Restart the presentation timer |
?, h | Toggle this help |
Esc | Back to slideshow |