Ver código
knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE, fig.retina = 3,
out.width = "80%")Checho
5 de octubre de 2022
Esta presentación se centra en algunos microaprendizajes de un proyecto de análisis de resultados de una encuesta de diversidad e inclusión.
Lo razón por la que lo llamo “microaprendizajes” es porque no tuve que aprender muchas cosas desde cero, pero si aprendí varios truquitos que me sirvieron mucho.
Voy a usar una encuesta simulada para no violar la confidencialidad de los datos, pero va a ser algo análogo a lo que estuve usando en el proyecto.
Para explotar al máximo esta sesión conviene saber un poco de hacer informes con RMarkdown. Si necesitás un tutorial sobre ese tema te comparto el video que hicimos el año pasado.

Este material se puede utilizar y compartir sin fines comerciales y citando la fuente.
El bloque de código de setup es muy útil para controlar cómo se van a comportar todos los bloques de código.
Mi archivo original tiene +150 bloques de código, imaginen si modificara uno por uno las características de cada bloque.
Tener un orden en el código es muy importante para poder ir y venir rápido y encontrar rápidamente las cosas, modificar algo, y demás.
Dentro de los bloques de código también es importante poner títulos o marcadores que nos ayuden a encontrar rápido las cosas. El orden que definí fue:
# Librerías -----
library(tidyverse)
library(gt)
library(scales)
library(extrafont)
library(readxl)
# Configuraciones generales ----------
# Colores
verde <- "#01B3B6"
negro <- "#333132"
gris <- "#AEB6BF"
color3 <- c(verde, gris, negro)
color2 <- c(verde, negro)
# Opciones de visualización --------
options(scipen = 999) # Modifica la visualización de los ejes numérico a valores nominales
loadfonts(quiet = TRUE) # Permite cargar en R otros tipos de fuentes.
# Estilo limpio sin líneas de fondo
estilo <- theme(panel.grid = element_blank(),
plot.background = element_rect(fill = "#FBFCFC"),
panel.background = element_blank(),
text = element_text(family = "Ubuntu Mono"))
# Estilo limpio con líneas de referencia verticales en gris claro
estilov <- theme(panel.grid = element_blank(),
plot.background = element_rect(fill = "#FBFCFC"),
panel.background = element_blank(),
panel.grid.major.x = element_line(color = "#ecf0f1"),
text = element_text(family = "Ubuntu Mono"))
# Estilo limpio con líneas de referencia horizontales en gris claro
estiloh <- theme(panel.grid = element_blank(),
plot.background = element_rect(fill = "#FBFCFC"),
panel.background = element_blank(),
panel.grid.major.y = element_line(color = "#ecf0f1"),
text = element_text(family = "Ubuntu Mono"))
# Creo un objeto con un texto que se va a repetir mucho a lo largo del análisis
fuente <- "Club de R para RRHH\nDatos Ficticios"
# Creo objetos para formatear las etiquetas numéricas de los ejes x e y
eje_x_per <- scale_x_continuous(labels = scales::percent_format(accuracy = 1))
eje_y_per <- scale_y_continuous(labels = scales::percent_format(accuracy = 1))
# Carga de Datos -----
encuesta <- read_excel("data/encuesta.xlsx")
plantel <- read_excel("data/plantel.xlsx")
# Preparación de datos -----------
# Pivotea el dataset a un formato largo
enc <- encuesta %>%
pivot_longer(cols = c(7:11),
names_to = "pregunta",
values_to = "valor")
# Cambia nombres y Organiza variables ordinales
enc <- enc %>%
rename(id = "ID",
genero = `¿Cómo definirías tu identidad de género?`,
unidad = "Unidad de Negocio",
pais = "País",
sector = "Sector",
cargo = "Tu cargo/nivel:") %>%
mutate(cargo = factor(cargo,
levels = c("Management", "Líder", "Contribuidor individual")))
# Crea categorías de resultados
enc <- enc %>%
mutate(resultado = if_else(valor == "Totalmente de acuerdo", "Positivo",
if_else(valor == "De acuerdo", "Positivo",
if_else(valor == "Ni de acuerdo ni en desacuerdo",
"Neutral", "Negativo"
)
)
),
resultado = factor(resultado,
levels = c("Positivo", "Neutral", "Negativo")))Y comenten el código por amor a Jebús!

Algo muy útil es ponerle nombre a los bloques de código. Por un lado porque es fácil para navegar entre bloques buscándolos en RStudio.
Por ejemplo, probemos un gráfico simple:

Puede ocurrir que necesitemos reutilizar el gráfico. Hacer la gran stackoverflow (copiar y pegar el código) es una opción, pero puede generar errores y por otro lado implica tiempo de procesamiento.
En cambio, con la opción ref.label podemos reutilizar lo que hicimos antes, de una forma más prolija y cómoda pasando el nombre del bloque anterior.
Internamente, lo que hace R es reutilizar el código creado anteriormente.
Voilá!
A veces necesitamos presentar en un gráfico o en una tabla la pregunta original de la encuesta. Por ejemplo, una de las “preguntas” de la encuesta dice:
Otra pregunta que tiene muchísimo texto escrito en la encuesta y quedó tan larga que no entra en un solo renglón y que me hace preguntarme cómo la voy a poner en un gráfico
Ahora veamos cómo se ven las preguntas en un gráfico si intentamos hacer un ranking.
enc %>%
group_by(pregunta, resultado) %>%
summarise(cant = n()) %>%
mutate(prop = cant/sum(cant)) %>%
filter(resultado == "Positivo") %>%
ggplot(aes(x = prop, y = pregunta)) +
geom_col(fill = verde) +
estilov +
eje_x_per +
labs(title = "Ranking de Respuestas Positivas",
x = "", y = "",
caption = fuente)
Queda hermoso, no? 😱
Para sortear este problema podemos crear una columna nueva, y usar la función str_wrap() del paquete stringr.
Lo que hace esto es agregar el símbolo \n que divide el texto en renglones. Con el parámetro width le indicamos la cantidad de caracteres de largo que tendrá cada renglón.
[1] "Una pregunta con un texto muy pero muy\npero muy largo, de verdad que es muy muy\nmuy largo"
[2] "Otra pregunta que tiene muchísimo texto\nescrito en la encuesta y quedó tan larga\nque no entra en un solo renglón y que me\nhace preguntarme cómo la voy a poner en\nun gráfico"
[3] "Los líderes son unos capos"
[4] "Que grosso es trabajar acá"
[5] "Esta encuesta es genial"
Y ahora podemos hacer un gráfico que se vea bien:
enc %>%
group_by(preg2, resultado) %>%
summarise(cant = n()) %>%
mutate(prop = cant/sum(cant)) %>%
filter(resultado == "Positivo") %>%
ggplot(aes(x = prop, y = reorder(preg2, prop))) +
geom_col(fill = verde) +
estilov +
eje_x_per +
labs(title = "Ranking de Respuestas Positivas",
x = "", y = "",
caption = fuente)
Ahora queda mucho mejor 👍
También se puede jugar con la altura del gráfico usando la opción fig.height en las opciones del bloque para que haya más espacio entre las barras.
ranking <- enc %>%
group_by(preg2, resultado) %>%
summarise(cant = n()) %>%
mutate(prop = cant/sum(cant)) %>%
filter(resultado == "Positivo") %>%
ggplot(aes(x = prop, y = reorder(preg2, prop))) +
geom_col(fill = verde) +
estilov +
eje_x_per +
labs(title = "Ranking de Respuestas Positivas",
x = "", y = "",
caption = fuente)
ranking
Es simple agregar las etiquetas de datos a un gráfico:

Miremos lo que pasa cuando queremos agregar más información al gráfico, por ejemplo, con los resultados por país.
ranking <- enc %>%
group_by(pais, preg2, resultado) %>%
summarise(cant = n()) %>%
mutate(prop = cant/sum(cant)) %>%
filter(resultado == "Positivo") %>%
ggplot(aes(x = prop, y = reorder(preg2, prop), fill = pais)) +
geom_col(position = "dodge") +
estilov +
eje_x_per +
labs(title = "Ranking de Respuestas Positivas",
x = "", y = "",
fill = "País",
caption = fuente) +
scale_fill_brewer(palette = 2)
ranking +
geom_text(aes(label = percent(prop, # Muestra los resultados como porcentaje
accuracy = 1)), # Indica la cantidad de decimales
size = 3, # Cambia el tamaño de la letra
hjust = 1.2, # Mueve la etiqueta para la izquierda
family = "Ubuntu Mono") # Modifica la fuente
El problema es que todas las etiquetas de cada barra están centradas con la etiqueta del eje y. En la guía de geom_text en la documentación de ggplot2 encontramos como solucionar el problema usando el parámetro position_dodge().
ranking <- ranking +
geom_text(aes(label = percent(prop, # Muestra los resultados como porcentaje
accuracy = 1)), # Indica la cantidad de decimales
position = position_dodge(0.9), # Acomoda cada etiqueta con las barras
size = 3, # Cambia el tamaño de la letra
hjust = 1.2, # Mueve la etiqueta para la izquierda
family = "Ubuntu Mono") # Modifica la fuente
ranking
Otra mejora que podemos hacer al gráfico es acomodar los colores en la leyenda (la referencia de los colores) para que tengan la misma secuencia que tiene en el gráfico, es decir que el verde oscuro aparezca primero al igual que la barra con el verde más oscuro en el gráfico.
En esta página hay muchas variantes para trabajar con las etiquetas y leyendas.

Cuando estamos mapeando una variable categórica en el eje y, R lo ordena alfabéticamente desde abajo hacia arriba.

Podemos usar la función fct_rev del paquete forcats para poner al revés las etiquetas del eje y cuando estamos mapeando las variables dentro de ggplot
enc %>%
group_by(sector, resultado) %>%
summarise(cant = n()) %>%
mutate(prop = cant/sum(cant)) %>%
filter(resultado == "Positivo") %>%
ggplot(aes(x = prop, y = fct_rev(sector))) + # Invertimos el orden del eje y
geom_col(fill = verde) +
estilov +
eje_x_per +
labs(title = "Resultado Positivos por Sector",
x = "", y = "",
caption = fuente)
Esto es un work-in-progress y tengo que agradecer a Mónica Alonso de RLadies Buenos Aires por la ayuda.
El problema es que me encontré muchas veces escribiendo esta secuencia de código muchas veces:
# A tibble: 6 × 4
# Groups: genero [2]
genero resultado cant prop
<chr> <fct> <int> <dbl>
1 Femenino Positivo 1127 0.764
2 Femenino Neutral 244 0.165
3 Femenino Negativo 104 0.0705
4 Masculino Positivo 1477 0.823
5 Masculino Neutral 222 0.124
6 Masculino Negativo 96 0.0535
Muchas veces resolví copiando y pegando el código, pero se hace tedioso controlar cada uno de los bloques de código y gráficos. Así que para eso, podemos crear nuestras propias funciones.
Y ahora lo podemos incorporar en nuestro flujo de trabajo como cualquier función.

Todavía estoy resolviendo como crear funciones usando cualquier tipo de variable en la función. Por ahora, lo estoy resolviendo creando una función para cada combinación de variables que agrupo. No es lo ideal, pero es lo que hay. 🤷
Capaz encuentre lo que necesito en estos libros:
Ya les contaré… stay tuned 📺
Como sabemos, algo interesante de RMarkdown es la posibilidad de utilizar el código de los bloques dentro del texto.
Así que creemos un pequeño objeto primero para almacenar los resultados positivos y negativos por género.
# A tibble: 6 × 4
# Groups: genero [2]
genero resultado cant prop
<chr> <fct> <int> <dbl>
1 Femenino Positivo 1127 0.764
2 Femenino Neutral 244 0.165
3 Femenino Negativo 104 0.0705
4 Masculino Positivo 1477 0.823
5 Masculino Neutral 222 0.124
6 Masculino Negativo 96 0.0535
Usando la llamada de datos de un dataframe con nombre_df[fila,columna] puedo usar los resultados almacenados para incluirlos dentro del texto por ejemplo para decir:
Los resultados positivos para las personas de género femenino es 0.7640678.
Lo ideal es poder ver ese resultado como un porcentaje, así que intuitivamente podemos usar la función percent para lograr eso…
…y no va a funcionar. Obtenemos el siguiente mensaje de error:
Para que la función percent funcione la tenemos que combinar con la función pull . Y ahora así sí funciona:
Los resultados positivos para las personas de género femenino es 76% .
Lo barato sale caro
Dicho popular

La encuesta que estábamos analizando era anónima, lo cual hacía imposible poder cruzar datos contra el listado de empleados.
Pero, sí podíamos calcular los resultados según la composición del liderazgo. Para eso teníamos que calcular el porcentaje de líderes hombres y mujeres por sector.
# A tibble: 106 × 6
pais division sector lider sexo n
<chr> <chr> <chr> <chr> <chr> <int>
1 Chad Unidad 1 Comercial true Femenino 4
2 Chad Unidad 1 Comercial true Masculino 3
3 Chad Unidad 1 R&D true Femenino 5
4 Chad Unidad 1 R&D true Masculino 1
5 Chad Unidad 2 Administración true Femenino 3
6 Chad Unidad 2 Administración true Masculino 6
7 Chad Unidad 2 Calidad true Femenino 1
8 Chad Unidad 2 Comercial true Femenino 5
9 Chad Unidad 2 Comercial true Masculino 1
10 Chad Unidad 2 Recursos Humanos true Femenino 3
# ℹ 96 more rows
# Pivoteo el dataset a un dataset ancho
plantel <- plantel %>%
pivot_wider(.,
names_from = sexo,
values_from = n)
# Reemplaza los NA con un 0
plantel[is.na(plantel)] <- 0
# Calculo porcentaje de líderes hombres
plantel %>%
mutate(prop_lider_hombre = if_else(Femenino == 0, 1, Masculino / (Masculino +Femenino))) %>%
select(-lider)# A tibble: 60 × 6
pais division sector Femenino Masculino prop_lider_hombre
<chr> <chr> <chr> <int> <int> <dbl>
1 Chad Unidad 1 Comercial 4 3 0.429
2 Chad Unidad 1 R&D 5 1 0.167
3 Chad Unidad 2 Administración 3 6 0.667
4 Chad Unidad 2 Calidad 1 0 0
5 Chad Unidad 2 Comercial 5 1 0.167
6 Chad Unidad 2 Recursos Humanos 3 0 0
7 Chad Unidad 3 Administración 2 2 0.5
8 Chad Unidad 3 Calidad 2 2 0.5
9 Chad Unidad 3 Comercial 5 20 0.8
10 Chad Unidad 3 HSE 1 0 0
# ℹ 50 more rows