Semana 8: de archivos municipales a tablas descriptivas

Análisis de Datos I

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

Universidad Católica de Temuco

2026-05-04

Propósito de la clase

La semana anterior fue reemplazada por una evaluación remedial. Por eso, antes de avanzar hacia el póster, necesitamos reforzar el paso que conecta la descarga de datos con el análisis.

No basta con descargar archivos desde Transparencia Activa.

Para analizarlos, necesitamos nombrarlos, identificarlos, limpiarlos, unirlos y resumirlos.

Ruta de trabajo de la semana

Hoy trabajaremos el siguiente flujo:

archivos descargados

nombres ordenados

variables identificadoras

estandarización de columnas

unión con bind_rows()

tablas descriptivas

exportación de resultados

¿Por qué esto importa para el póster?

El póster no parte con el diseño visual.

Parte con una base que permita responder una pregunta descriptiva.

Para eso necesitamos:

  • una fuente clara
  • un periodo definido
  • variables identificadoras
  • una base reproducible
  • tablas y gráficos que salgan desde código
  • decisiones metodológicas documentadas.

Tema del ejercicio

Trabajaremos con información de Transparencia Activa municipal.

En particular:

Remuneraciones mensuales informadas por municipios, desde marzo de 2023 hasta marzo de 2026, según disponibilidad.

Tipos de personal incluidos

Para el trabajo del curso se considerarán los cuatro tipos de personal:

Tipo de personal Descripción general
Planta Personal permanente de la dotación municipal
Contrata Personal contratado por periodos definidos
Código del Trabajo Personal sujeto al Código del Trabajo
Honorarios Personas naturales contratadas para prestación de servicios

Criterio común

El análisis principal debe incluir los cuatro tipos de personal, pero siempre distinguiendo el tipo de vínculo contractual.

No se debe mezclar planta, contrata, Código del Trabajo y honorarios como si fueran equivalentes.

Unidad institucional

Transparencia Activa puede separar la información en:

  • Municipalidad
  • Departamento de Administración de Educación Municipal
  • Departamento de Salud.

Para el póster, el criterio base será trabajar con:

Municipalidad como unidad institucional principal.

¿Por qué con Municipalidad?

Porque permite mantener mayor comparabilidad.

DAEM y Salud tienen:

  • funciones sectoriales distintas
  • dotaciones más especializadas
  • composiciones ocupacionales diferentes
  • escalas y cargos no siempre comparables con la administración municipal general.

Nombres de archivos

Cada grupo descargará varios archivos por mes y por tipo de personal (desde la web de transparencia de su municipio).

Obligatoriamente, guardaremos los archivos en una carpeta llamada “datos_raw” dentro de nuestro proyecto, y los archivos se denominaran con una estructura común:

municipio_tipo_mes_anio.csv

Ejemplos:

vilcun_planta_marzo_2026.csv
vilcun_contrata_marzo_2026.csv
vilcun_cdt_marzo_2026.csv
vilcun_honorarios_marzo_2026.csv

Nombres que debemos evitar

archivo1.csv
remuneraciones.csv
datos.csv
marzo.csv
final.csv

Problema

Esos nombres no permiten saber qué contiene el archivo, de qué mes viene ni a qué tipo de personal corresponde.

¿Por qué el nombre del archivo no basta?

Porque cuando unimos muchos archivos en una sola base, el nombre del archivo deja de estar visible.

Por eso, cada fila debe conservar información mínima sobre su origen.

Variables identificadoras obligatorias

Cada archivo debe incorporar estas variables antes de unirse:

Variable Ejemplo Función
municipio "Vilcún" Identifica la comuna
tipo_personal "contrata" Distingue el vínculo contractual
anio 2026 Identifica el año
mes "marzo" Identifica el mes
mes_num 3 Permite ordenar cronológicamente
periodo "2026-03" Facilita series temporales

¿Qué pasa si no agregamos identificadores?

Cuando unimos los archivos, perdemos trazabilidad.

Después no sabremos:

  • si una fila viene de planta, contrata, CDT u honorarios
  • si corresponde a marzo de 2026 u otro periodo
  • si pertenece a Municipalidad, DAEM o Salud
  • desde qué archivo fue cargada.

Importante

Una base analizable debe conservar siempre la historia mínima de cada fila.

Estructura recomendada del proyecto

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

Dos formas de combinar bases

Hoy distinguiremos dos operaciones:

Operación Qué hace Ejemplo en este trabajo
bind_rows() Apila filas Juntar planta, contrata, CDT y honorarios
join Agrega columnas desde otra base Agregar provincia, región o población comunal

Tipos de unión de bases de datos

No todas las uniones de bases sirven para lo mismo.
Antes de elegir un comando, debemos preguntarnos:

¿Queremos sumar registros o queremos agregar información?

Tipos de unión de bases de datos

Operación ¿Qué hace? ¿Cuándo se usa?
bind_rows() Apila filas Cuando tengo varios archivos con la misma lógica de registros
left_join() Agrega columnas y conserva todos los casos de la base principal Cuando quiero sumar información contextual
inner_join() Conserva solo los casos que aparecen en ambas bases Cuando quiero quedarme solo con coincidencias exactas
full_join() Conserva todos los casos de ambas bases Cuando quiero combinar fuentes sin perder registros
anti_join() Muestra casos de una base que no aparecen en otra Cuando quiero detectar problemas de emparejamiento
semi_join() Conserva casos de la primera base que sí tienen coincidencia en la segunda, sin agregar columnas Cuando quiero filtrar según existencia en otra base

bind_rows()

Usamos bind_rows() cuando tenemos archivos con registros similares y queremos construir una sola base larga.

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

¿Qué hace bind_rows()?

Imaginemos cuatro bases:

planta
contrata
cdt
honorarios

Cada una contiene registros mensuales de personas o prestaciones informadas.

Con bind_rows() obtenemos:

remuneraciones
├── registros de planta
├── registros de contrata
├── registros de Código del Trabajo
└── registros de honorarios

¿Cuándo usamos join?

Usamos join cuando queremos agregar columnas desde otra base.

Por ejemplo, una base auxiliar de municipios:

municipio provincia region poblacion
Vilcún Cautín La Araucanía 30000
Temuco Cautín La Araucanía 280000

Ejemplo de left_join()

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

Esto no suma más personas.

Agrega columnas de contexto a los registros existentes.

En fácil

Si quiero sumar registros, uso bind_rows().

Si quiero agregar información (variables) sobre esos registros, uso join.

¿Cuál usaremos en el ejercicio?

Para construir la base de remuneraciones usaremos principalmente:

bind_rows()

Porque queremos apilar archivos mensuales y tipos de personal.

Los join los revisaremos como herramienta complementaria.

Datos reales de ejemplo

En el laboratorio usaremos archivos tipo de Vilcún (pueden usar los de su municipio):

planta_marzo_2026.csv
contrata_marzo_26.csv
cdt_marzo_26.csv
honorarios_26.csv

Estos archivos tienen estructuras parecidas, pero no idénticas.

Columnas frecuentes en planta y contrata

Planta y contrata incluyen, entre otras:

  • Año
  • Mes
  • Estamento
  • Nombre completo
  • Cargo o función
  • Grado EUS o jornada
  • Calificación profesional o formación
  • Remuneración bruta
  • Remuneración líquida
  • Fecha de inicio
  • Fecha de término
  • Observaciones.

Honorarios tiene otra estructura

Honorarios incluye, entre otras:

  • Año
  • Mes
  • Nombre completo
  • Descripción de la función
  • Calificación profesional o formación
  • Honorario Total Bruto del mes
  • Honorario Total Líquido del mes
  • Tipo de pago
  • Número de cuotas
  • Fecha de inicio
  • Fecha de término
  • Observaciones.

Problema metodológico

No podemos unir directamente bases con estructuras distintas sin tomar decisiones.

Necesitamos crear nombres comunes.

Planta / Contrata / CDT Honorarios Nombre común
Cargo o función Descripción de la función funcion
Remuneración bruta del mes Honorario Total Bruto del mes monto_bruto
Remuneración líquida del mes Honorario Total Líquido del mes monto_liquido
Fecha de inicio Fecha de inicio fecha_inicio
Fecha de término Fecha de término fecha_termino

Base final esperada

Una vez procesados los archivos, la base debería tener columnas como:

municipio
unidad
tipo_personal
anio
mes
mes_num
periodo
nombre
estamento
funcion
formacion
monto_bruto
monto_liquido
fecha_inicio
fecha_termino
observaciones
archivo_origen

¿Qué hacemos con columnas que no existen?

Algunas columnas existen en una base, pero no en otra.

Por ejemplo:

  • honorarios no tiene estamento
  • planta y contrata no tienen tipo_pago
  • CDT puede tener columnas distintas de horas extra.

En esos casos, se puede crear la columna con NA.

estamento = NA_character_

Limpieza de montos

Los montos suelen venir como texto:

$ 1.737.854
-
No informa

Antes de calcular promedios, medianas o totales, deben transformarse a números.

Ejemplo de limpieza

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

¿Qué tablas podemos construir?

Una vez unida la base, podemos construir tablas como:

  • número de registros por tipo de personal
  • remuneración promedio por tipo de personal
  • remuneración mediana por tipo de personal
  • casos sin monto informado
  • comparación entre planta, contrata, CDT y honorarios.

Tabla descriptiva esperada

tipo_personal registros promedio bruto mediana bruto sin monto
planta
contrata
codigo_trabajo
honorarios

Cómo interpretar la tabla

Una buena interpretación debe incluir:

  1. qué muestra la tabla
  2. qué resultado destaca
  3. qué cifra respalda el resultado
  4. qué precaución metodológica debe considerarse.

Ejemplo de interpretación

La tabla resume las remuneraciones brutas informadas por tipo de vínculo contractual en la Municipalidad de Vilcún durante marzo de 2026. Permite observar diferencias descriptivas en el número de registros y en los montos informados entre planta, contrata, Código del Trabajo y honorarios. Sin embargo, estas diferencias deben interpretarse con cautela, porque los tipos de vínculo no necesariamente corresponden a funciones, jornadas o responsabilidades equivalentes.

Buenas prácticas

Buena práctica 1: conservar el archivo original

Nunca editar manualmente el archivo descargado.

El archivo original queda en:

datos_raw/

La base procesada queda en:

datos_clean/

Buena práctica 2: documentar decisiones

Ejemplos de decisiones que deben quedar escritas:

  • se trabajó con Municipalidad
  • se incluyeron los cuatro tipos de personal
  • se limpió el símbolo $ de los montos
  • se transformaron los montos a numéricos
  • se creó la variable periodo
  • se usó bind_rows() porque se quería apilar registros.

Buena práctica 3: revisar antes de calcular

Antes de hacer tablas:

glimpse(remuneraciones)
summary(remuneraciones$monto_bruto)
count(remuneraciones, tipo_personal)

Buena práctica 4: separar exploración y presentación

Una tabla exploratoria sirve para revisar.

Una tabla de presentación sirve para comunicar.

No todas las tablas que hacemos deben ir al póster.

Buena práctica 5: reportar fuente y periodo

Toda tabla debe indicar:

  • fuente
  • municipio
  • unidad institucional
  • periodo
  • tipos de personal incluidos.

Paquetes para hacer tablas en R

En R no existe una sola forma de hacer tablas.

La elección del paquete depende de qué necesitamos hacer con la tabla:

  • explorar datos rápidamente
  • construir una tabla descriptiva
  • preparar una tabla para Word
  • exportar resultados a Excel
  • crear una tabla visual para un póster
  • generar una tabla para un informe en Quarto.

Paquetes más usados para tablas

Paquete Mejor uso Ventaja Precaución
dplyr Construir tablas desde cero Permite entender qué se está calculando Requiere más pasos
janitor Frecuencias y tablas cruzadas Muy simple para porcentajes Menos flexible para formato final
flextable Tablas para Word Buena integración con .docx Puede requerir ajustes de formato
gt Tablas para HTML, imagen o póster Muy buena presentación visual Exportar a imagen puede requerir configuración extra
gtsummary Tablas descriptivas tipo artículo Genera tablas completas rápidamente Puede ocultar la lógica del cálculo
writexl Exportar resultados a Excel Simple y liviano No mejora la estética de la tabla
kableExtra Tablas en HTML/PDF Útil para informes en Quarto En PDF puede depender de LaTeX

¿Cuál usamos según el objetivo?

Objetivo Paquete recomendado
Contar casos dplyr::count()
Frecuencias y porcentajes rápidos janitor::tabyl()
Resúmenes por grupo dplyr::group_by() + summarise()
Exportar a Word flextable + officer
Exportar a Excel writexl
Tabla visual para póster gt
Tabla descriptiva avanzada gtsummary
Tabla para PDF/HTML en Quarto knitr::kable() o kableExtra

Recomendación para este curso

Para la Evaluación 2, usaremos una lógica simple:

Flujo recomendado

  1. Construir la tabla con dplyr o janitor.
  2. Revisar si los resultados tienen sentido.
  3. Preparar una versión limpia para presentar.
  4. Exportar según el formato necesario:
    • Word: flextable
    • Excel: writexl
    • imagen/póster: gt
    • Quarto: tabla directa, knitr::kable() o kableExtra.

Próxima parte: laboratorio

En el laboratorio vamos a:

  1. cargar archivos reales de sus comunas
  2. agregar variables identificadoras
  3. estandarizar columnas
  4. unir archivos con bind_rows()
  5. revisar un ejemplo breve de left_join()
  6. construir tablas descriptivas
  7. exportar resultados.