============================================================
# Instalar paquetes solo si aĂșn no estĂĄn instalados
paquetes <- c("haven", "dplyr", "tidyr", "ggplot2", "forcats", "scales","ggforce")
paquetes_faltantes <- paquetes[!paquetes %in% installed.packages()[, "Package"]]
if (length(paquetes_faltantes) > 0) {
install.packages(paquetes_faltantes)
}
# Cargar paquetes
library(haven)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tidyr)
library(ggplot2)
library(forcats)
library(scales)
library(ggforce)
# ------------------------------------------------------------
# 1. Leer la base
# ------------------------------------------------------------
datos <- read_sav("ECETSS_ocupados.sav")
# Verificar que las variables requeridas existan
variables_necesarias <- c(
"recomp_valorac",
"C3P16.1",
"nivel_ed",
"region",
"C0P10.3",
"sector",
"ramacaes_o"
)
variables_faltantes <- setdiff(variables_necesarias, names(datos))
if (length(variables_faltantes) > 0) {
stop(
paste(
"No se encontraron estas variables en la base:",
paste(variables_faltantes, collapse = ", ")
)
)
}
# ------------------------------------------------------------
# 2. Preparar la base y traducir las variables
# ------------------------------------------------------------
base_reconocimiento <- datos %>%
transmute(
frecuencia_valoracion = as.character(as_factor(recomp_valorac)),
sexo = as.character(as_factor(`C3P16.1`)),
nivel_educativo = as.character(as_factor(nivel_ed)),
region = as.character(as_factor(region)),
edad = as.numeric(`C0P10.3`),
sector = as.character(as_factor(sector)),
rama_actividad = as.character(as_factor(ramacaes_o))
) %>%
mutate(
# RecodificaciĂłn de edades a rango etario
rango_etario = case_when(
edad >= 15 & edad <= 19 ~ "15 a 19 años",
edad >= 20 & edad <= 29 ~ "20 a 29 años",
edad >= 30 & edad <= 39 ~ "30 a 39 años",
edad >= 40 & edad <= 49 ~ "40 a 49 años",
edad >= 50 & edad <= 59 ~ "50 a 59 años",
edad >= 60 & edad <= 69 ~ "60 a 69 años",
edad >= 70 & edad <= 79 ~ "70 a 79 años",
edad >= 80 & edad <= 89 ~ "80 a 89 años",
TRUE ~ NA_character_
),
# RecodificaciĂłn de la frecuencia de valoraciĂłn
nivel_reconocimiento = case_when(
frecuencia_valoracion %in% c("Siempre", "Muchas veces") ~ "Alto",
frecuencia_valoracion == "Algunas veces" ~ "Medio",
frecuencia_valoracion %in% c("Solo alguna vez", "Nunca") ~ "Bajo",
frecuencia_valoracion %in% c("No corresponde", "Ns/Nc") ~ "S/R",
TRUE ~ NA_character_
),
# Orden de las categorĂas para tablas y grĂĄficos
sexo = factor(sexo, levels = c("VarĂłn", "Mujer")),
nivel_reconocimiento = factor(
nivel_reconocimiento,
levels = c("Alto", "Medio", "Bajo", "S/R")
),
frecuencia_valoracion = factor(
frecuencia_valoracion,
levels = c(
"Siempre",
"Muchas veces",
"Algunas veces",
"Solo alguna vez",
"Nunca",
"No corresponde",
"Ns/Nc"
)
)
) %>%
filter(!is.na(sexo), !is.na(nivel_reconocimiento))
# Colores para los grĂĄficos
colores_reconocimiento <- c(
"Alto" = "#1B9E77",
"Medio" = "#E6AB02",
"Bajo" = "#D95F02",
"S/R" = "#7570B3"
)
# Crear carpeta para guardar los grĂĄficos
if (!dir.exists("graficos_reconocimiento")) {
dir.create("graficos_reconocimiento")
}
# Referencia general de reconocimiento Alto segĂșn sexo
referencia_alto_sexo <- base_reconocimiento %>%
filter(nivel_reconocimiento %in% c("Alto", "Medio", "Bajo")) %>%
group_by(sexo) %>%
summarise(
referencia_alto = mean(
as.character(nivel_reconocimiento) == "Alto"
),
.groups = "drop"
)
referencia_alto_sexo
# ------------------------------------------------------------
# 3. Cruce inicial: frecuencia de valoraciĂłn segĂșn sexo
# Se excluyen Ns/Nc y No corresponde del grĂĄfico
# ------------------------------------------------------------
# Tabla para el grĂĄfico:
# los porcentajes se calculan solo entre Alto, Medio y Bajo.
tabla_frecuencia_sexo <- base_reconocimiento %>%
filter(nivel_reconocimiento %in% c("Alto", "Medio", "Bajo")) %>%
count(sexo, nivel_reconocimiento, name = "casos") %>%
group_by(sexo) %>%
mutate(
porcentaje = round(100 * casos / sum(casos), 1)
) %>%
ungroup()
tabla_frecuencia_sexo
# Tabla de control: casos excluidos del grĂĄfico
tabla_sr_sexo <- base_reconocimiento %>%
filter(nivel_reconocimiento == "S/R") %>%
count(sexo, name = "casos_sin_respuesta") %>%
left_join(
base_reconocimiento %>%
count(sexo, name = "total_respondentes"),
by = "sexo"
) %>%
mutate(
porcentaje_sin_respuesta = round(
100 * casos_sin_respuesta / total_respondentes,
1
)
)
tabla_sr_sexo
# Colores solicitados
colores_grafico <- c(
"Alto" = "#58A65C",
"Medio" = "#A6A6A6",
"Bajo" = "#F4A6B5"
)
# GrĂĄfico
grafico_frecuencia_sexo <- ggplot(
tabla_frecuencia_sexo,
aes(x = sexo, y = porcentaje, fill = nivel_reconocimiento)
) +
geom_col(width = 0.65, color = "white", linewidth = 0.6) +
geom_text(
aes(label = paste0(porcentaje, "%")),
position = position_stack(vjust = 0.5),
color = "black",
fontface = "bold",
size = 4
) +
scale_fill_manual(
values = colores_grafico,
breaks = c("Alto", "Medio", "Bajo")
) +
scale_y_continuous(
labels = function(x) paste0(x, "%"),
breaks = seq(0, 100, 25),
expand = c(0, 0)
) +
coord_cartesian(ylim = c(0, 100)) +
labs(
title = "Reconocimiento laboral segĂșn sexo",
subtitle = "Porcentaje dentro de cada sexo",
x = NULL,
y = "Porcentaje",
fill = "Nivel de reconocimiento",
caption = paste(
"Alto: siempre o muchas veces. Medio: algunas veces. Bajo: solo alguna vez o nunca.",
"No corresponde y Ns/Nc se excluyen del grĂĄfico; ver tabla de control."
)
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold"),
legend.position = "bottom",
panel.grid.major.x = element_blank(),
plot.caption.position = "plot",
plot.caption = element_text(hjust = 0, size = 8)
)
grafico_frecuencia_sexo

ggsave(
"graficos_reconocimiento/01_reconocimiento_segun_sexo.png",
grafico_frecuencia_sexo,
width = 10,
height = 7,
dpi = 300
)
# ============================================================
# 4. FUNCIĂN PARA GRĂFICOS CON BRECHA Y REFERENCIA GENERAL
# ============================================================
colores_grafico <- c(
"Alto" = "#58A65C",
"Medio" = "#A6A6A6",
"Bajo" = "#F4A6B5"
)
crear_grafico_brecha <- function(
base,
variable,
titulo_variable,
orden = NULL,
excluidos = character(0),
archivo,
alto = 9
) {
# Preparar la variable a analizar
base_grafico <- base %>%
transmute(
sexo = factor(as.character(sexo), levels = c("VarĂłn", "Mujer")),
grupo = trimws(as.character(.data[[variable]])),
nivel_reconocimiento = factor(
as.character(nivel_reconocimiento),
levels = c("Alto", "Medio", "Bajo")
)
) %>%
filter(!is.na(sexo), !is.na(grupo))
# Tabla de control de categorĂas excluidas
tabla_excluidos <- base_grafico %>%
filter(grupo %in% excluidos) %>%
count(grupo, sexo, name = "casos") %>%
mutate(
porcentaje_muestra = round(
100 * casos / nrow(base_grafico),
2
)
)
print(tabla_excluidos)
# Datos que se usarĂĄn en el grĂĄfico
base_grafico <- base_grafico %>%
filter(
!grupo %in% excluidos,
nivel_reconocimiento %in% c("Alto", "Medio", "Bajo")
)
# Orden de las categorĂas
categorias_presentes <- unique(base_grafico$grupo)
if (is.null(orden)) {
orden_final <- sort(categorias_presentes)
} else {
orden_final <- c(
orden[orden %in% categorias_presentes],
setdiff(categorias_presentes, orden)
)
}
base_grafico <- base_grafico %>%
mutate(
grupo = factor(
grupo,
levels = orden_final,
ordered = TRUE
)
)
# Tabla para las barras
tabla <- base_grafico %>%
count(grupo, sexo, nivel_reconocimiento, name = "casos") %>%
complete(
grupo,
sexo,
nivel_reconocimiento,
fill = list(casos = 0)
)
# Proporciones dentro de cada sexo y categorĂa
tabla_pct <- tabla %>%
group_by(grupo, sexo) %>%
mutate(proporcion = casos / sum(casos)) %>%
ungroup()
# Brecha de reconocimiento Alto: VarĂłn menos Mujer
df_gap <- tabla_pct %>%
filter(nivel_reconocimiento == "Alto") %>%
select(grupo, sexo, proporcion) %>%
pivot_wider(
names_from = sexo,
values_from = proporcion,
values_fill = 0
) %>%
mutate(
brecha_pp = (`VarĂłn` - Mujer) * 100,
brecha_texto = paste0(
ifelse(brecha_pp > 0, "+", ""),
round(brecha_pp, 1),
" pp"
)
)
# Datos para los Ăłvalos azules
df_ovalo <- df_gap %>%
select(grupo, Mujer, `VarĂłn`) %>%
pivot_longer(
cols = c(Mujer, `VarĂłn`),
names_to = "sexo",
values_to = "proporcion_alto"
) %>%
mutate(
sexo = factor(sexo, levels = c("VarĂłn", "Mujer"))
)
# Datos para los diamantes:
# referencia general de Alto segĂșn sexo
df_diamante <- tidyr::expand_grid(
grupo = factor(
levels(tabla$grupo),
levels = levels(tabla$grupo),
ordered = TRUE
),
sexo = factor(
c("VarĂłn", "Mujer"),
levels = c("VarĂłn", "Mujer")
)
) %>%
left_join(
referencia_alto_sexo,
by = "sexo"
)
# GrĂĄfico
grafico <- ggplot(
data = tabla,
aes(
x = casos,
y = sexo,
fill = nivel_reconocimiento
)
) +
# Barras: Alto verde a la izquierda
geom_col(
position = position_fill(reverse = TRUE),
color = "white",
linewidth = 0.4
) +
# Ăvalo azul: diferencia de Alto entre VarĂłn y Mujer
ggforce::geom_mark_ellipse(
data = df_ovalo,
aes(
x = proporcion_alto,
y = sexo,
group = grupo
),
inherit.aes = FALSE,
color = "#1976D2",
fill = NA,
linewidth = 0.9,
expand = grid::unit(2.5, "mm")
) +
# Diamante: valor general de reconocimiento Alto por sexo
geom_point(
data = df_diamante,
aes(
x = referencia_alto,
y = sexo,
shape = "Promedio general de Alto"
),
inherit.aes = FALSE,
size = 3.8,
stroke = 1,
fill = "#58A65C",
color = "white"
) +
# Brecha en puntos porcentuales
geom_text(
data = df_gap,
aes(
y = "Mujer",
label = brecha_texto
),
x = 1.05,
inherit.aes = FALSE,
hjust = 0,
color = "gray30",
fontface = "bold",
size = 3
) +
facet_grid(
grupo ~ .,
switch = "y",
labeller = labeller(grupo = label_wrap_gen(18))
) +
scale_fill_manual(
values = colores_grafico,
breaks = c("Alto", "Medio", "Bajo")
) +
scale_shape_manual(
name = "Referencia",
values = c("Promedio general de Alto" = 23)
) +
scale_x_continuous(
labels = scales::percent,
breaks = seq(0, 1, by = 0.25),
expand = c(0, 0)
) +
coord_cartesian(
xlim = c(0, 1.15),
clip = "off"
) +
guides(
fill = guide_legend(order = 1),
shape = guide_legend(order = 2)
) +
labs(
title = paste(
"Nivel de reconocimiento laboral segĂșn sexo\ny",
tolower(titulo_variable)
),
subtitle = paste(
"DistribuciĂłn porcentual dentro de cada sexo y",
tolower(titulo_variable)
),
x = "Porcentaje",
y = NULL,
fill = "Nivel de reconocimiento",
caption = paste(
"Alto: siempre o muchas veces. Medio: algunas veces. Bajo: solo alguna vez o nunca.\n",
"Los Ăłvalos azules y los valores en pp indican la brecha de reconocimiento Alto ",
"(diferencia entre VarĂłn y Mujer).\n",
"El diamante verde representa el promedio general de reconocimiento Alto para cada sexo."
)
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(
face = "bold",
size = 14,
lineheight = 0.9
),
legend.position = "bottom",
strip.text.y.left = element_text(
angle = 0,
face = "bold",
size = 8,
lineheight = 0.9,
margin = margin(r = 6)
),
strip.placement = "outside",
axis.text.y = element_text(size = 8),
panel.grid.major.y = element_blank(),
panel.spacing.y = grid::unit(0.15, "lines"),
plot.caption.position = "plot",
plot.caption = element_text(hjust = 0, size = 8)
)
print(grafico)
ggsave(
paste0("graficos_reconocimiento/", archivo),
grafico,
width = 12,
height = alto,
dpi = 300
)
return(
list(
tabla = tabla,
tabla_excluidos = tabla_excluidos,
brechas = df_gap,
grafico = grafico
)
)
}
# ============================================================
# ĂRDENES DE LAS CATEGORĂAS
# ============================================================
orden_nivel_educativo <- c(
"Posgrado completo",
"Posgrado incompleto",
"Universitario completo",
"Universitario incompleto",
"Terciario completo",
"Terciario incompleto",
"Secundario completo",
"Secundario incompleto",
"Primario completo",
"Primario incompleto",
"Sin instrucciĂłn"
)
orden_region <- c(
"Gran Buenos Aires",
"Pampeana",
"NOA",
"NEA",
"Patagonia",
"Cuyo"
)
orden_rango_etario <- c(
"80 a 89 años",
"70 a 79 años",
"60 a 69 años",
"50 a 59 años",
"40 a 49 años",
"30 a 39 años",
"20 a 29 años",
"15 a 19 años"
)
orden_sector <- c(
"Privado",
"PĂșblico o estatal",
"De otro tipo"
)
orden_rama_actividad <- c(
"Actividades primarias",
"Industria manufacturera",
"ConstrucciĂłn",
"Comercio",
"Hoteles y restaurantes",
"Transporte, alm y comunic",
"Serv financ, inm, alq y emp",
"AdministraciĂłn pĂșblica y defensa",
"Enseñanza",
"Servicios sociales y de salud",
"Otros serv comunit, soc y per",
"Trabajo doméstico",
"Otras ramas"
)
# ============================================================
# GRĂFICOS
# ============================================================
resultado_nivel_educativo <- crear_grafico_brecha(
base = base_reconocimiento,
variable = "nivel_educativo",
titulo_variable = "Nivel educativo",
orden = orden_nivel_educativo,
excluidos = c("Ns/Nc", "S/R"),
archivo = "02_reconocimiento_sexo_nivel_educativo.png",
alto = 14
)
## # A tibble: 2 Ă 4
## grupo sexo casos porcentaje_muestra
## <chr> <fct> <int> <dbl>
## 1 Ns/Nc VarĂłn 6 0.07
## 2 Ns/Nc Mujer 6 0.07

resultado_region <- crear_grafico_brecha(
base = base_reconocimiento,
variable = "region",
titulo_variable = "RegiĂłn",
orden = orden_region,
archivo = "03_reconocimiento_sexo_region.png",
alto = 8
)
## # A tibble: 0 Ă 4
## # âč 4 variables: grupo <chr>, sexo <fct>, casos <int>, porcentaje_muestra <dbl>

resultado_rango_etario <- crear_grafico_brecha(
base = base_reconocimiento,
variable = "rango_etario",
titulo_variable = "Rango etario",
orden = orden_rango_etario,
archivo = "04_reconocimiento_sexo_rango_etario.png",
alto = 10
)
## # A tibble: 0 Ă 4
## # âč 4 variables: grupo <chr>, sexo <fct>, casos <int>, porcentaje_muestra <dbl>

resultado_sector <- crear_grafico_brecha(
base = base_reconocimiento,
variable = "sector",
titulo_variable = "Sector de ocupaciĂłn",
orden = orden_sector,
excluidos = c("Ns/Nc", "S/R"),
archivo = "05_reconocimiento_sexo_sector.png",
alto = 7
)
## # A tibble: 2 Ă 4
## grupo sexo casos porcentaje_muestra
## <chr> <fct> <int> <dbl>
## 1 Ns/Nc VarĂłn 1 0.01
## 2 Ns/Nc Mujer 2 0.02

resultado_rama_actividad <- crear_grafico_brecha(
base = base_reconocimiento,
variable = "rama_actividad",
titulo_variable = "Rama de actividad",
orden = orden_rama_actividad,
excluidos = c("Sin especificar", "Ns/Nc", "S/R"),
archivo = "06_reconocimiento_sexo_rama_actividad.png",
alto = 16
)
## # A tibble: 2 Ă 4
## grupo sexo casos porcentaje_muestra
## <chr> <fct> <int> <dbl>
## 1 Sin especificar VarĂłn 17 0.19
## 2 Sin especificar Mujer 6 0.07
