Semana 8: laboratorio de remuneraciones municipales

Construcción de base, tablas y exportación

Dr.(c) César Marcelo Ávila Fuentes

Universidad Católica de Temuco

2026-05-04

Objetivo

Construir una base de remuneraciones municipales a partir de archivos descargados desde Transparencia Activa.

En este laboratorio vamos a:

  1. cargar archivos CSV
  2. agregar variables identificadoras
  3. estandarizar columnas
  4. unir archivos usando bind_rows()
  5. revisar brevemente un ejemplo de left_join()
  6. construir tablas descriptivas
  7. exportar resultados a Word, Excel e imagen.

1. Preparar el proyecto

La carpeta del proyecto debería tener una estructura parecida a esta:

semana8_remuneraciones/
├── datos_raw/
│   ├── planta_marzo_2026.csv
│   ├── contrata_marzo_26.csv
│   ├── cdt_marzo_26.csv
│   └── honorarios_26.csv
├── datos_clean/
├── outputs/
├── scripts/
└── semana8_laboratorio_remuneraciones.qmd

2. Cargar paquetes

library(dplyr)
library(readr)
library(janitor)
library(stringr)
library(flextable)
library(officer)
library(writexl)
library(gt)

Recordar primero instalar en caso de no contar en la biblioteca con los paquetes antes mencionados.

3. Cargar archivos

Los archivos vienen separados por punto y coma, por eso usaremos read_csv2().

planta <- read_csv2("datos_raw/planta_marzo_2026.csv", locale = locale(encoding = "Latin1")) |>
  clean_names()

contrata <- read_csv2("datos_raw/contrata_marzo_26.csv", locale = locale(encoding = "Latin1")) |>
  clean_names()

cdt <- read_csv2("datos_raw/cdt_marzo_26.csv", locale = locale(encoding = "Latin1")) |>
  clean_names()

honorarios <- read_csv2("datos_raw/honorarios_26.csv", locale = locale(encoding = "Latin1")) |>
  clean_names()

4. Revisar nombres de variables

Antes de limpiar, debemos mirar qué columnas trae cada archivo.

names(planta)
names(contrata)
names(cdt)
names(honorarios)

4. Revisar nombres de variables Planta

Antes de limpiar, debemos mirar qué columnas trae cada archivo.

names(planta)
 [1] "ano"                                                                               
 [2] "mes"                                                                               
 [3] "estamento"                                                                         
 [4] "nombre_completo"                                                                   
 [5] "cargo_o_funcion"                                                                   
 [6] "grado_eus_o_jornada"                                                               
 [7] "calificacion_profesional_o_formacion"                                              
 [8] "region"                                                                            
 [9] "asignaciones_especiales_del_mes_inc_en_rem_bruta"                                  
[10] "remuneracion_bruta_del_mes_incluye_bonos_e_incentivos_asig_especiales_horas_extras"
[11] "remuneracion_liquida_del_mes"                                                      
[12] "rem_adicionales_del_mes_no_inc_en_rem_bruta"                                       
[13] "remuneracion_bonos_incentivos_del_mes_inc_en_rem_bruta"                            
[14] "derecho_a_horas_extraordinarias"                                                   
[15] "montos_y_horas_extraordinarias_diurnas_del_mes_inc_en_rem_bruta"                   
[16] "montos_y_horas_extraordinarias_nocturnas_del_mes_inc_en_rem_bruta"                 
[17] "montos_y_horas_extraordinarias_festivas_del_mes_inc_en_rem_bruta"                  
[18] "fecha_de_inicio_dd_mm_aa"                                                          
[19] "fecha_de_termino_dd_mm_aa"                                                         
[20] "observaciones"                                                                     
[21] "viaticos_del_mes_no_inc_en_rem_bruta"                                              
[22] "x22"                                                                               

4. Revisar nombres de variables Contrata

Antes de limpiar, debemos mirar qué columnas trae cada archivo.

names(contrata)
 [1] "ano"                                                                               
 [2] "mes"                                                                               
 [3] "estamento"                                                                         
 [4] "nombre_completo"                                                                   
 [5] "cargo_o_funcion"                                                                   
 [6] "grado_eus_o_jornada"                                                               
 [7] "calificacion_profesional_o_formacion"                                              
 [8] "region"                                                                            
 [9] "asignaciones_especiales_del_mes_inc_en_rem_bruta"                                  
[10] "remuneracion_bruta_del_mes_incluye_bonos_e_incentivos_asig_especiales_horas_extras"
[11] "remuneracion_liquida_del_mes"                                                      
[12] "rem_adicionales_del_mes_no_inc_en_rem_bruta"                                       
[13] "remuneracion_bonos_incentivos_del_mes_inc_en_rem_bruta"                            
[14] "derecho_a_horas_extraordinarias"                                                   
[15] "montos_y_horas_extraordinarias_diurnas_del_mes_inc_en_rem_bruta"                   
[16] "montos_y_horas_extraordinarias_nocturnas_del_mes_inc_en_rem_bruta"                 
[17] "montos_y_horas_extraordinarias_festivas_del_mes_inc_en_rem_bruta"                  
[18] "fecha_de_inicio_dd_mm_aa"                                                          
[19] "fecha_de_termino_dd_mm_aa"                                                         
[20] "viaticos_del_mes_no_inc_en_rem_bruta"                                              
[21] "observaciones"                                                                     
[22] "x22"                                                                               

4. Revisar nombres de variables Código del Trabajo

Antes de limpiar, debemos mirar qué columnas trae cada archivo.

names(cdt)
 [1] "ano"                                                                               
 [2] "mes"                                                                               
 [3] "nombre_completo"                                                                   
 [4] "cargo_o_funcion"                                                                   
 [5] "grado_eus_o_jornada"                                                               
 [6] "calificacion_profesional_o_formacion"                                              
 [7] "region"                                                                            
 [8] "asignaciones_especiales_del_mes_inc_en_rem_bruta"                                  
 [9] "remuneracion_bruta_del_mes_incluye_bonos_e_incentivos_asig_especiales_horas_extras"
[10] "remuneracion_liquida_del_mes"                                                      
[11] "rem_adicionales_del_mes_no_inc_en_rem_bruta"                                       
[12] "remuneracion_bonos_incentivos_del_mes_inc_en_rem_bruta"                            
[13] "monto_de_desvinculacion_no_inc_en_rem_bruta"                                       
[14] "derecho_a_horas_extraordinarias"                                                   
[15] "montos_y_horas_extraordinarias_del_mes_inc_en_rem_bruta"                           
[16] "viaticos_del_mes_no_inc_en_rem_bruta"                                              
[17] "fecha_de_inicio_dd_mm_aaaa"                                                        
[18] "fecha_de_termino_dd_mm_aaaa"                                                       
[19] "observaciones"                                                                     
[20] "x20"                                                                               

4. Revisar nombres de variables Honorarios

Antes de limpiar, debemos mirar qué columnas trae cada archivo.

names(honorarios)
 [1] "ano"                                 
 [2] "mes"                                 
 [3] "nombre_completo"                     
 [4] "grado_eus_si_corresponde"            
 [5] "descripcion_de_la_funcion"           
 [6] "calificacion_profesional_o_formacion"
 [7] "region"                              
 [8] "honorario_total_bruto_del_mes"       
 [9] "honorario_total_liquido_del_mes"     
[10] "tipo_de_pago"                        
[11] "descripcion_pago"                    
[12] "numero_de_cuotas"                    
[13] "fecha_de_inicio"                     
[14] "fecha_de_termino"                    
[15] "observaciones"                       
[16] "enlace_funciones_desarrolladas"      
[17] "viaticos"                            
[18] "x18"                                 

5. Revisar estructura general

glimpse(planta)

5. Revisar estructura general

glimpse(planta)
Rows: 72
Columns: 22
$ ano                                                                                <dbl> …
$ mes                                                                                <chr> …
$ estamento                                                                          <chr> …
$ nombre_completo                                                                    <chr> …
$ cargo_o_funcion                                                                    <chr> …
$ grado_eus_o_jornada                                                                <dbl> …
$ calificacion_profesional_o_formacion                                               <chr> …
$ region                                                                             <chr> …
$ asignaciones_especiales_del_mes_inc_en_rem_bruta                                   <chr> …
$ remuneracion_bruta_del_mes_incluye_bonos_e_incentivos_asig_especiales_horas_extras <chr> …
$ remuneracion_liquida_del_mes                                                       <chr> …
$ rem_adicionales_del_mes_no_inc_en_rem_bruta                                        <chr> …
$ remuneracion_bonos_incentivos_del_mes_inc_en_rem_bruta                             <chr> …
$ derecho_a_horas_extraordinarias                                                    <chr> …
$ montos_y_horas_extraordinarias_diurnas_del_mes_inc_en_rem_bruta                    <chr> …
$ montos_y_horas_extraordinarias_nocturnas_del_mes_inc_en_rem_bruta                  <chr> …
$ montos_y_horas_extraordinarias_festivas_del_mes_inc_en_rem_bruta                   <chr> …
$ fecha_de_inicio_dd_mm_aa                                                           <chr> …
$ fecha_de_termino_dd_mm_aa                                                          <chr> …
$ observaciones                                                                      <chr> …
$ viaticos_del_mes_no_inc_en_rem_bruta                                               <chr> …
$ x22                                                                                <lgl> …
glimpse(contrata)
Rows: 56
Columns: 22
$ ano                                                                                <dbl> …
$ mes                                                                                <chr> …
$ estamento                                                                          <chr> …
$ nombre_completo                                                                    <chr> …
$ cargo_o_funcion                                                                    <chr> …
$ grado_eus_o_jornada                                                                <dbl> …
$ calificacion_profesional_o_formacion                                               <chr> …
$ region                                                                             <chr> …
$ asignaciones_especiales_del_mes_inc_en_rem_bruta                                   <chr> …
$ remuneracion_bruta_del_mes_incluye_bonos_e_incentivos_asig_especiales_horas_extras <chr> …
$ remuneracion_liquida_del_mes                                                       <chr> …
$ rem_adicionales_del_mes_no_inc_en_rem_bruta                                        <chr> …
$ remuneracion_bonos_incentivos_del_mes_inc_en_rem_bruta                             <chr> …
$ derecho_a_horas_extraordinarias                                                    <chr> …
$ montos_y_horas_extraordinarias_diurnas_del_mes_inc_en_rem_bruta                    <chr> …
$ montos_y_horas_extraordinarias_nocturnas_del_mes_inc_en_rem_bruta                  <chr> …
$ montos_y_horas_extraordinarias_festivas_del_mes_inc_en_rem_bruta                   <chr> …
$ fecha_de_inicio_dd_mm_aa                                                           <chr> …
$ fecha_de_termino_dd_mm_aa                                                          <chr> …
$ viaticos_del_mes_no_inc_en_rem_bruta                                               <chr> …
$ observaciones                                                                      <chr> …
$ x22                                                                                <lgl> …
glimpse(cdt)
Rows: 5
Columns: 20
$ ano                                                                                <dbl> …
$ mes                                                                                <chr> …
$ nombre_completo                                                                    <chr> …
$ cargo_o_funcion                                                                    <chr> …
$ grado_eus_o_jornada                                                                <chr> …
$ calificacion_profesional_o_formacion                                               <chr> …
$ region                                                                             <chr> …
$ asignaciones_especiales_del_mes_inc_en_rem_bruta                                   <chr> …
$ remuneracion_bruta_del_mes_incluye_bonos_e_incentivos_asig_especiales_horas_extras <chr> …
$ remuneracion_liquida_del_mes                                                       <chr> …
$ rem_adicionales_del_mes_no_inc_en_rem_bruta                                        <chr> …
$ remuneracion_bonos_incentivos_del_mes_inc_en_rem_bruta                             <chr> …
$ monto_de_desvinculacion_no_inc_en_rem_bruta                                        <chr> …
$ derecho_a_horas_extraordinarias                                                    <chr> …
$ montos_y_horas_extraordinarias_del_mes_inc_en_rem_bruta                            <chr> …
$ viaticos_del_mes_no_inc_en_rem_bruta                                               <chr> …
$ fecha_de_inicio_dd_mm_aaaa                                                         <chr> …
$ fecha_de_termino_dd_mm_aaaa                                                        <chr> …
$ observaciones                                                                      <chr> …
$ x20                                                                                <lgl> …
glimpse(honorarios)
Rows: 204
Columns: 18
$ ano                                  <dbl> 2026, 2026, 2026, 2026, 2026, 202…
$ mes                                  <chr> "Marzo", "Marzo", "Marzo", "Marzo…
$ nombre_completo                      <chr> "Acuña Cerda, Jenifer Haydee", "A…
$ grado_eus_si_corresponde             <chr> "No asimilado a grado", "No asimi…
$ descripcion_de_la_funcion            <chr> "Prestacion de servicios Programa…
$ calificacion_profesional_o_formacion <chr> "Profesora Educación Fisica", "En…
$ region                               <chr> "Región de La Araucanía", "Región…
$ honorario_total_bruto_del_mes        <chr> "$ 1.462.759", "$ 636.008", "$ 22…
$ honorario_total_liquido_del_mes      <chr> "-", "-", "-", "-", "-", "-", "-"…
$ tipo_de_pago                         <chr> "Pago mensual", "Pago mensual", "…
$ descripcion_pago                     <chr> "-", "-", "-", "-", "-", "-", "-"…
$ numero_de_cuotas                     <chr> "-", "-", "-", "-", "-", "-", "-"…
$ fecha_de_inicio                      <chr> "02/01/2026", "01/01/2026", "05/0…
$ fecha_de_termino                     <chr> "31/12/2026", "31/12/2026", "30/0…
$ observaciones                        <chr> "decreto 415; decreto 874 17/02/2…
$ enlace_funciones_desarrolladas       <chr> "No publica", "No publica", "No p…
$ viaticos                             <chr> "No informa", "No informa", "No i…
$ x18                                  <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…

6. Agregar identificadores

Cada archivo debe conservar información sobre su origen.

Planta

planta <- planta |>
  mutate(
    municipio = "Vilcún",
    unidad = "Municipalidad",
    tipo_personal = "planta",
    anio = 2026,
    mes = "marzo",
    mes_num = 3,
    periodo = "2026-03"
  )

Contrata

contrata <- contrata |>
  mutate(
    municipio = "Vilcún",
    unidad = "Municipalidad",
    tipo_personal = "contrata",
    anio = 2026,
    mes = "marzo",
    mes_num = 3,
    periodo = "2026-03"
  )

Código del Trabajo

cdt <- cdt |>
  mutate(
    municipio = "Vilcún",
    unidad = "Municipalidad",
    tipo_personal = "codigo_trabajo",
    anio = 2026,
    mes = "marzo",
    mes_num = 3,
    periodo = "2026-03"
  )

Honorarios

honorarios <- honorarios |>
  mutate(
    municipio = "Vilcún",
    unidad = "Municipalidad",
    tipo_personal = "honorarios",
    anio = 2026,
    mes = "marzo",
    mes_num = 3,
    periodo = "2026-03"
  )

7. Estandarizar columnas

Los archivos no tienen exactamente las mismas columnas. Por eso construiremos una versión simplificada de cada base.

Planta simplificada

planta_simple <- planta |>
  transmute(
    municipio,
    unidad,
    tipo_personal,
    anio,
    mes,
    mes_num,
    periodo,
    nombre = nombre_completo,
    estamento = estamento,
    funcion = cargo_o_funcion,
    grado_jornada = grado_eus_o_jornada,
    formacion = calificacion_profesional_o_formacion,
    region = region,
    monto_bruto = remuneracion_bruta_del_mes_incluye_bonos_e_incentivos_asig_especiales_horas_extras,
    monto_liquido = remuneracion_liquida_del_mes,
    fecha_inicio = fecha_de_inicio_dd_mm_aa,
    fecha_termino = fecha_de_termino_dd_mm_aa,
    observaciones = observaciones
  )

Contrata simplificada

contrata_simple <- contrata |>
  transmute(
    municipio,
    unidad,
    tipo_personal,
    anio,
    mes,
    mes_num,
    periodo,
    nombre = nombre_completo,
    estamento = estamento,
    funcion = cargo_o_funcion,
    grado_jornada = grado_eus_o_jornada,
    formacion = calificacion_profesional_o_formacion,
    region = region,
    monto_bruto = remuneracion_bruta_del_mes_incluye_bonos_e_incentivos_asig_especiales_horas_extras,
    monto_liquido = remuneracion_liquida_del_mes,
    fecha_inicio = fecha_de_inicio_dd_mm_aa,
    fecha_termino = fecha_de_termino_dd_mm_aa,
    observaciones = observaciones
  )

Código del Trabajo simplificado

cdt_simple <- cdt |>
  transmute(
    municipio,
    unidad,
    tipo_personal,
    anio,
    mes,
    mes_num,
    periodo,
    nombre = nombre_completo,
    estamento = NA_character_,
    funcion = cargo_o_funcion,
    grado_jornada = grado_eus_o_jornada,
    formacion = calificacion_profesional_o_formacion,
    region = region,
    monto_bruto = remuneracion_bruta_del_mes_incluye_bonos_e_incentivos_asig_especiales_horas_extras,
    monto_liquido = remuneracion_liquida_del_mes,
    fecha_inicio = fecha_de_inicio_dd_mm_aaaa,
    fecha_termino = fecha_de_termino_dd_mm_aaaa,
    observaciones = observaciones
  )

Honorarios simplificada

honorarios_simple <- honorarios |>
  transmute(
    municipio,
    unidad,
    tipo_personal,
    anio,
    mes,
    mes_num,
    periodo,
    nombre = nombre_completo,
    estamento = NA_character_,
    funcion = descripcion_de_la_funcion,
    grado_jornada = grado_eus_si_corresponde,
    formacion = calificacion_profesional_o_formacion,
    region = region,
    monto_bruto = honorario_total_bruto_del_mes,
    monto_liquido = honorario_total_liquido_del_mes,
    fecha_inicio = fecha_de_inicio,
    fecha_termino = fecha_de_termino,
    observaciones = observaciones
  )

8. Preparar tipos de columnas antes de unir

Antes de apilar las bases, conviene asegurar que las columnas comunes tengan el mismo tipo. En estos archivos, por ejemplo, grado_jornada puede venir como número en una base y como texto en otra. Eso hace que bind_rows() se detenga.

Primero generaremos un conjunto, con los nombres de las variables que debiesen ser reconocidas como texto

columnas_texto <- c(
  "municipio", "unidad", "tipo_personal", "mes", "periodo",
  "nombre", "estamento", "funcion", "grado_jornada", "formacion",
  "region", "monto_bruto", "monto_liquido", "fecha_inicio",
  "fecha_termino", "observaciones", "archivo_origen"
)

8. Preparar tipos de columnas antes de unir

Luego vamos a aplicar para cada elemento de esa lista de variables, la opción de ser conocida como texto (character)

planta_simple <- planta_simple |>
  mutate(across(any_of(columnas_texto), as.character))

contrata_simple <- contrata_simple |>
  mutate(across(any_of(columnas_texto), as.character))

cdt_simple <- cdt_simple |>
  mutate(across(any_of(columnas_texto), as.character))

honorarios_simple <- honorarios_simple |>
  mutate(across(any_of(columnas_texto), as.character))

9. Unir archivos con bind_rows()

Como queremos apilar registros, usamos bind_rows().

remuneraciones <- bind_rows(
  planta_simple,
  contrata_simple,
  cdt_simple,
  honorarios_simple
)

10. Revisar base unida

glimpse(remuneraciones)
Rows: 337
Columns: 18
$ municipio     <chr> "Vilcún", "Vilcún", "Vilcún", "Vilcún", "Vilcún", "Vilcú…
$ unidad        <chr> "Municipalidad", "Municipalidad", "Municipalidad", "Muni…
$ tipo_personal <chr> "planta", "planta", "planta", "planta", "planta", "plant…
$ anio          <dbl> 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026, 20…
$ mes           <chr> "marzo", "marzo", "marzo", "marzo", "marzo", "marzo", "m…
$ mes_num       <dbl> 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,…
$ periodo       <chr> "2026-03", "2026-03", "2026-03", "2026-03", "2026-03", "…
$ nombre        <chr> "ALFARO PULGAR, PABLO  ESTEBAN", "ALVIAL RIVERA, VIVIANA…
$ estamento     <chr> "Técnico", "Profesional", "Técnico", "Administrativo", "…
$ funcion       <chr> "TÉCNICO ADMINISTRACIÓN MUNICIPAL", "PROFESIONAL OBRAS M…
$ grado_jornada <chr> "14", "11", "16", "17", "7", "9", "15", "17", "17", "7",…
$ formacion     <chr> "Técnico en Amplificación", "Ingeniero Civil", "Técnico …
$ region        <chr> "Región de La Araucanía", "Región de La Araucanía", "Reg…
$ monto_bruto   <chr> "$ 1.737.854", "$ 2.426.876", "$ 1.314.239", "$ 892.019"…
$ monto_liquido <chr> "$", "$", "$", "$", "$", "$", "$", "$", "$", "$", "$", "…
$ fecha_inicio  <chr> "01/06/2015", "03/11/2020", "25/03/2019", "17/11/2025", …
$ fecha_termino <chr> "Indefinido", "Indefinido", "Indefinido", "30/06/2026", …
$ observaciones <chr> "Sin Observaciones", "Sin Observaciones", "Sin Observaci…

10. Revisar base unida

remuneraciones |>
  count(tipo_personal)
# A tibble: 4 × 2
  tipo_personal      n
  <chr>          <int>
1 codigo_trabajo     5
2 contrata          56
3 honorarios       204
4 planta            72

11. Limpiar montos

summary(remuneraciones$monto_bruto)
   Length     Class      Mode 
      337 character character 
remuneraciones |>
  summarise(
    casos = n(),
    sin_monto_bruto = sum(is.na(monto_bruto)),
    sin_monto_liquido = sum(is.na(monto_liquido))
  )
# A tibble: 1 × 3
  casos sin_monto_bruto sin_monto_liquido
  <int>           <int>             <int>
1   337               0                 0

11. Limpiar montos

Los montos vienen como texto. Necesitamos convertirlos a números.

Como este proceso lo tendremos que repetir, generaremos una función, así podemos replicar este proceso solo escribiendo el nombre de la función posteriormente.

limpiar_monto <- function(x) {
  x |>
    str_remove_all("\\$") |>
    str_remove_all("\\.") |>
    str_trim() |>
    na_if("-") |>
    na_if("") |>
    na_if("No informa") |>
    as.numeric()
}

11. Limpiar montos

remuneraciones <- remuneraciones |>
  mutate(
    monto_bruto = limpiar_monto(monto_bruto),
    monto_liquido = limpiar_monto(monto_liquido)
  )

12. Revisar montos limpios

summary(remuneraciones$monto_bruto)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  47334  500000  885765 1015447 1294552 7008009 
remuneraciones |>
  summarise(
    casos = n(),
    sin_monto_bruto = sum(is.na(monto_bruto)),
    sin_monto_liquido = sum(is.na(monto_liquido))
  )
# A tibble: 1 × 3
  casos sin_monto_bruto sin_monto_liquido
  <int>           <int>             <int>
1   337               0               337

13. Tabla de frecuencia por tipo de personal

tabla_tipo <- remuneraciones |>
  count(tipo_personal, name = "registros") |>
  mutate(
    porcentaje = round(registros / sum(registros) * 100, 1)
  )

tabla_tipo
# A tibble: 4 × 3
  tipo_personal  registros porcentaje
  <chr>              <int>      <dbl>
1 codigo_trabajo         5        1.5
2 contrata              56       16.6
3 honorarios           204       60.5
4 planta                72       21.4

14. Tabla descriptiva de remuneraciones

tabla_remuneraciones <- remuneraciones |>
  group_by(tipo_personal) |>
  summarise(
    registros = n(),
    promedio_bruto = round(mean(monto_bruto, na.rm = TRUE), 0),
    mediana_bruto = round(median(monto_bruto, na.rm = TRUE), 0),
    minimo_bruto = min(monto_bruto, na.rm = TRUE),
    maximo_bruto = max(monto_bruto, na.rm = TRUE),
    sin_monto = sum(is.na(monto_bruto)),
    .groups = "drop"
  )

14. Tabla descriptiva de remuneraciones

tabla_remuneraciones
# A tibble: 4 × 7
  tipo_personal registros promedio_bruto mediana_bruto minimo_bruto maximo_bruto
  <chr>             <int>          <dbl>         <dbl>        <dbl>        <dbl>
1 codigo_traba…         5         446342        120448        47334       976221
2 contrata             56        1109228        917666       525133      2540591
3 honorarios          204         662758        636008        53340      1890000
4 planta               72        1981312       1582105        86621      7008009
# ℹ 1 more variable: sin_monto <int>

15. Mejorar tabla para presentación

tabla_presentacion <- tabla_remuneraciones |>
  rename(
    `Tipo de personal` = tipo_personal,
    `Registros` = registros,
    `Promedio bruto` = promedio_bruto,
    `Mediana bruto` = mediana_bruto,
    `Mínimo bruto` = minimo_bruto,
    `Máximo bruto` = maximo_bruto,
    `Sin monto informado` = sin_monto
  )

15. Mejorar tabla para presentación

tabla_presentacion
# A tibble: 4 × 7
  `Tipo de personal` Registros `Promedio bruto` `Mediana bruto` `Mínimo bruto`
  <chr>                  <int>            <dbl>           <dbl>          <dbl>
1 codigo_trabajo             5           446342          120448          47334
2 contrata                  56          1109228          917666         525133
3 honorarios               204           662758          636008          53340
4 planta                    72          1981312         1582105          86621
# ℹ 2 more variables: `Máximo bruto` <dbl>, `Sin monto informado` <int>

16. Convertir a flextable

tabla_flex <- tabla_presentacion |>
  flextable() |>
  set_caption("Tabla 1. Remuneraciones brutas por tipo de personal. Municipalidad de Vilcún, marzo 2026") |>
  autofit()

tabla_flex

Tipo de personal

Registros

Promedio bruto

Mediana bruto

Mínimo bruto

Máximo bruto

Sin monto informado

codigo_trabajo

5

446,342

120,448

47,334

976,221

0

contrata

56

1,109,228

917,666

525,133

2,540,591

0

honorarios

204

662,758

636,008

53,340

1,890,000

0

planta

72

1,981,312

1,582,105

86,621

7,008,009

0

17. Exportar a Word

dir.create("outputs", showWarnings = FALSE)

doc <- read_docx()

doc <- doc |>
  body_add_par("Resultados descriptivos preliminares", style = "heading 1") |>
  body_add_par("Tabla 1. Remuneraciones brutas por tipo de personal", style = "heading 2") |>
  body_add_flextable(tabla_flex) |>
  body_add_par(
    "Fuente: elaboración propia a partir de Transparencia Activa, Municipalidad de Vilcún, marzo 2026.",
    style = "Normal"
  )

print(doc, target = "outputs/tabla_remuneraciones_vilcun.docx")

18. Exportar a Excel

write_xlsx(
  list(
    tabla_tipo_personal = tabla_tipo,
    tabla_remuneraciones = tabla_presentacion
  ),
  path = "outputs/tablas_remuneraciones_vilcun.xlsx"
)

19. Como imagen gt

tabla_gt <- tabla_presentacion |>
  gt() |>
  tab_header(
    title = "Remuneraciones brutas por tipo de personal",
    subtitle = "Municipalidad de Vilcún, marzo 2026"
  ) |>
  tab_source_note(
    source_note = "Fuente: Transparencia Activa."
  )

gtsave(tabla_gt, "outputs/tabla.png")

20. Guardar base limpia

dir.create("datos_clean", showWarnings = FALSE)

saveRDS(
  remuneraciones,
  file = "datos_clean/remuneraciones_vilcun_marzo_2026.rds"
)

21. Ejemplo breve de left_join()

Ahora imaginemos que queremos agregar información externa del municipio.

datos_municipio <- tibble(
  municipio = "Vilcún",
  provincia = "Cautín",
  region_administrativa = "La Araucanía",
  tipo_comuna = "Municipio de referencia para ejercicio"
)

Usamos left_join() porque queremos agregar columnas, no filas.

remuneraciones_contexto <- remuneraciones |>
  left_join(datos_municipio, by = "municipio")

21. Ejemplo breve de left_join()

Revisamos:

remuneraciones_contexto |>
  select(municipio, provincia, region_administrativa, tipo_comuna, tipo_personal) |>
  head()
# A tibble: 6 × 5
  municipio provincia region_administrativa tipo_comuna            tipo_personal
  <chr>     <chr>     <chr>                 <chr>                  <chr>        
1 Vilcún    Cautín    La Araucanía          Municipio de referenc… planta       
2 Vilcún    Cautín    La Araucanía          Municipio de referenc… planta       
3 Vilcún    Cautín    La Araucanía          Municipio de referenc… planta       
4 Vilcún    Cautín    La Araucanía          Municipio de referenc… planta       
5 Vilcún    Cautín    La Araucanía          Municipio de referenc… planta       
6 Vilcún    Cautín    La Araucanía          Municipio de referenc… planta       

22. Diferencia práctica

nrow(remuneraciones)
[1] 337
nrow(remuneraciones_contexto)
[1] 337

El número de filas no cambia, porque left_join() agregó columnas de contexto.

23. Actividad práctica

Cada grupo debe adaptar el script a su municipio.

Debe entregar una carpeta con:

outputs/
├── tabla_remuneraciones_municipio.docx
├── tablas_remuneraciones_municipio.xlsx
└── tabla_remuneraciones_municipio.png

datos_clean/
└── remuneraciones_municipio_marzo_2026.rds

24. Interpretación breve

Escriba un párrafo de 5 a 7 líneas que responda:

  1. ¿qué muestra la tabla?
  2. ¿qué tipo de personal concentra más registros?
  3. ¿qué diferencias se observan en remuneración bruta?
  4. ¿qué limitación debe considerarse?

Cierre

El objetivo de este laboratorio no es solo producir una tabla.

El objetivo es construir una base trazable, ordenada y reproducible, que luego pueda alimentar el póster descriptivo.