1 Introducción

El 26 de agosto de 2026, en el marco de la huelga médica, el Sindicato Nacional de Médicos (Sinamed) sostuvo que otorgar el ajuste salarial reclamado “sería una inversión en salud”: pagar mejor a los médicos —argumentan— evitaría gastos mucho mayores por complicaciones y traslados de pacientes que hoy no encuentran especialistas, sobre todo en el interior. (Fuente periodística: https://www.abc.com.py/politica/2026/08/26/huelga-de-medicos-ajuste-salarial-seria-una-inversion-en-salud-dice-sinamed/)

Las afirmaciones concretas que se pueden contrastar con datos son:

# Afirmación del Sinamed ¿Contrastable con la nómina SFP?
H1 El salario médico no se ajusta desde 2012; hoy ronda ₲ 5.000.000. Parcial: la SFP publica 2016→2026. Sí se puede medir la trayectoria nominal y real.
H2 En 2012 un médico ganaba 2,8 salarios mínimos; hoy 1,5. El mínimo subió 79,8 % en 14 años. Sí: se compara la remuneración médica con el Salario Mínimo (SMM) vigente cada año.
H3 Piden pasar de ₲ 5.000.000 a ₲ 8.000.000; el costo sería ≈ USD 120 millones/año. Sí, de forma aproximada: nº de médicos × brecha × 12–13 pagos.
H4 El ajuste “sería una inversión”: se paga solo evitando complicaciones y traslados. No de forma directa con la nómina. Se plantea como análisis de punto de equilibrio (cuánto habría que ahorrar para que el gasto se autofinancie).

Qué puede y qué no puede probar este trabajo. La nómina de la SFP permite medir con rigor la erosión del salario médico (H1, H2) y dimensionar el costo fiscal del pedido (H3). No contiene información clínica ni de traslados, por lo que la tesis central —que el ajuste “se paga solo” (H4)— sólo se aborda como escenario, no como resultado demostrado.

2 Objetivos

2.1 General

Evaluar, con la nómina de pagos de la Secretaría de la Función Pública (SFP) del Ministerio de Salud Pública y Bienestar Social (MSPBS), en qué medida los datos respaldan el argumento del Sinamed de que el ajuste salarial reclamado constituye “una inversión en salud”.

2.2 Específicos

  1. Reconstruir la remuneración mensual individual de los médicos del MSPBS, julio de cada año, 2016–2026.
  2. Medir su evolución nominal y real (deflactada por IPC) y compararla con el resto del MSPBS y con el Salario Mínimo.
  3. Estimar el costo fiscal de llevar el piso de ₲ 5.000.000 a ₲ 8.000.000 y confrontarlo con la cifra de USD 120 millones citada por el gremio.
  4. Plantear el punto de equilibrio del argumento de “inversión”: qué ahorro por médico/año haría que el ajuste se autofinancie.

3 Fuente de datos

  • Nómina de funcionarios de la SFP (planilla mensual de julio), https://datos.sfp.gov.py/data/funcionarios/download. Se usa la base ya filtrada al MSPBS y guardada en formato fst (fpsalud_filtrada.fst).
  • Salario Mínimo Mensual (SMM) vigente en julio de cada año — decretos del Poder Ejecutivo (serie en el chunk series_externas).
  • Índice de Precios al Consumidor (IPC), promedio anual, base 2010 = 100 — Banco Mundial / BCP. 2026 es proyección (parámetro ipc_2026).
  • Tipo de cambio ₲/USD de referencia — parámetro gs_por_usd.

4 Gestión de datos

4.1 Series externas (SMM, IPC, tipo de cambio)

Salario Mínimo e IPC usados como referencia
anho smm ipc deflactor
2016 1964507 129.93 1.52
2017 2041123 134.61 1.47
2018 2112562 139.96 1.41
2019 2192839 143.82 1.38
2020 2192839 146.36 1.35
2021 2289324 153.37 1.29
2022 2550307 168.35 1.18
2023 2680373 176.15 1.12
2024 2798309 182.90 1.08
2025 2899048 190.29 1.04
2026 3044000 197.90 1.00

4.2 Lectura y saneamiento de la nómina

## Filas con pago (julio, todas las entidades = MSPBS): 1.145.391
## Años disponibles: 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026

4.3 Identificación de los médicos

profesion sólo está cargada desde 2017; en cambio cargo y funcion contienen la palabra médico también en años tempranos y en residentes cuya profesion figura como “BACHILLER”. Por eso se marca como médico/a la fila que menciona medicina en cualquiera de los tres campos, y luego se define un panel estable: quien fue clasificado médico/a alguna vez se considera médico/a en todos los años en que aparece. Así se corrige la cobertura despareja de los campos entre años.

Panel de médicos/as del MSPBS (julio de cada año)
anho medicos % con >1 línea principal_mediana total_mediana
2.016 6.842 77 4.200.000 8.363.636
2.017 7.177 75 4.200.000 8.363.636
2.018 7.393 71 4.516.364 8.736.000
2.019 7.920 71 4.536.000 9.032.728
2.020 8.887 75 4.536.000 9.034.182
2.021 9.112 73 4.536.000 9.072.000
2.022 9.881 73 4.536.000 8.949.091
2.023 10.436 77 4.579.985 9.669.802
2.024 10.939 83 4.863.636 9.727.273
2.025 11.702 72 5.454.545 9.090.910
2.026 8.621 55 4.000.000 8.000.000

Nota sobre 2026. La descarga de julio-2026 (obtenida en agosto-2026) trae ~57.700 filas frente a ~130.000 en 2025: es una planilla preliminar (faltan guardias, honorarios y personal aún no liquidado). Los valores de 2026 se muestran punteados y no se usan para las conclusiones principales.

4.4 Carga horaria (jornada laboral)

El campo carga_horaria es texto libre con el horario del cargo (“LUNES A VIERNES DE 07:00 A 13:00 HS”). Se convierte a horas semanales parseando el rango diario y el número de días, y sumando guardias explícitas. La cobertura del campo es baja antes de 2021 (25–45 %) y alta después (72–98 %), por lo que no se usa como serie temporal, sólo para caracterizar la jornada típica del cargo médico base.

5 Resultados

5.1 H1 — ¿El salario médico quedó congelado? Nominal vs. real

Remuneración mensual mediana de médicos/as del MSPBS. Valores reales en ₲ de 2026.
anho principal_nom total_nom principal_real total_real total_smm principal_smm
2.016 4.200.000 8.363.636 6.397.137 12.738.887 4.26 2.14
2.017 4.200.000 8.363.636 6.174.727 12.295.993 4.10 2.06
2.018 4.516.364 8.736.000 6.386.028 12.352.489 4.14 2.14
2.019 4.536.000 9.032.728 6.241.652 12.429.265 4.12 2.07
2.020 4.536.000 9.034.182 6.133.332 12.215.528 4.12 2.07
2.021 4.536.000 9.072.000 5.852.999 11.705.997 3.96 1.98
2.022 4.536.000 8.949.091 5.332.191 10.519.900 3.51 1.78
2.023 4.579.985 9.669.802 5.145.496 10.863.774 3.61 1.71
2.024 4.863.636 9.727.273 5.262.513 10.525.026 3.48 1.74
2.025 5.454.545 9.090.910 5.672.681 9.454.470 3.14 1.88
2.026 4.000.000 8.000.000 4.000.000 8.000.000 2.63 1.31

  • Remuneración total mediana nominal: ₲ 8.363.636 (2016) → ₲ 9.090.910 (2025) = 8.7% en 9 años.
  • Inflación acumulada 2016→2025 (IPC): 46.5%.
  • Remuneración total mediana real (₲ de 2026): ₲ 12.738.887 → ₲ 9.454.470 = -25.8%.

El salario médico no siguió el ritmo de los precios. Aunque hubo pequeños aumentos nominales, el poder adquisitivo de la mediana cayó alrededor de un cuarto entre 2016 y 2025. Esto es consistente con H1, con el matiz de que la SFP no permite retroceder hasta 2012.

5.1.1 Prueba con cohorte fija (los mismos médicos)

Para descartar que la caída se deba a un cambio de composición (entran médicos jóvenes peor pagos), se sigue a los mismos médicos presentes en 2017 y en 2025.

## Médicos presentes en 2017 y 2025: 5828
## Cambio real mediano de su remuneración 2017→2025: -9.0%
## Proporción que perdió poder adquisitivo: 61.3%

Incluso quienes permanecieron en el MSPBS —y acumularon antigüedad, que juega a su favor— perdieron en términos reales (mediana ≈ -9.0%), y 6 de cada 10 están peor que en 2017. La erosión no es un efecto de composición.

5.2 H2 — Salario médico medido en salarios mínimos

  • El SMM subió 54.9% entre julio-2016 y julio-2026 (el Sinamed cita +79,8 % sobre 14 años, base 2012: coherente).
  • Cargo principal (un puesto): de 2.14 SMM (2016) a 1.88 SMM (2025).
  • Remuneración total: de 4.26 SMM a 3.14 SMM.

La afirmación “de 2,8 a 1,5 SMM” describe el sueldo de un cargo y toma como base 2012. Con datos SFP desde 2016, el sueldo de un puesto médico pasó de ~2,1 a ~1,8–1,9 SMM (y 1,7 en 2024). La dirección y el orden de magnitud del reclamo se verifican; el valor exacto “1,5” depende de la base 2012 (fuera del alcance de la SFP) y de tomar el piso nominal fijo de ₲ 5.000.000.

5.3 H2 bis — Indicador de suficiencia por hora: ¿la brecha con el mínimo cambia al considerar la jornada?

La comparación anterior enfrenta el sueldo de un cargo médico (jornada parcial, típicamente 30 h/semana — el turno “lunes a viernes de 07:00 a 13:00”) con un Salario Mínimo que remunera una jornada plena de 48 h/semana. Son horas distintas. El indicador de suficiencia por hora las pone en la misma base:

\[\text{ratio hora} = \frac{\text{₲/hora del cargo médico}}{\text{₲/hora del SMM}} = \frac{\text{sueldo del cargo} \,/\, (30\cdot 52/12)} {\text{SMM} \,/\, (48\cdot 52/12)}\]

Jornada semanal de la línea principal de los médicos, distribución en % (años con buena cobertura del campo).
Año ≤20 h 21–30 h 31–40 h >40 h cobertura del campo (%)
2021 52 16 17 15 84
2022 54 18 17 11 74
2023 57 19 18 5 72
2024 48 17 18 17 79
2025 54 19 16 11 86
Número de cargos / líneas de pago por médico y año
Año líneas de pago (mediana) % con ≥2 líneas
2016 2 77
2017 2 75
2018 2 71
2019 2 71
2020 2 75
2021 2 73
2022 2 73
2023 2 77
2024 2 83
2025 2 72
2026 2 55
Suficiencia del cargo médico frente al Salario Mínimo: por mes vs. por hora. Jornada médica base = 30 h/sem; SMM = 48 h/sem.
Año Ratio mensual (cargo/SMM) Ratio hora (30 h) Ratio hora (sens. 24 h) Ratio hora (sens. 40 h)
2016 2.14 3.42 4.28 2.57
2017 2.06 3.29 4.12 2.47
2018 2.14 3.42 4.28 2.57
2019 2.07 3.31 4.14 2.48
2020 2.07 3.31 4.14 2.48
2021 1.98 3.17 3.96 2.38
2022 1.78 2.85 3.56 2.13
2023 1.71 2.73 3.42 2.05
2024 1.74 2.78 3.48 2.09
2025 1.88 3.01 3.76 2.26

  • La jornada del cargo médico no cambió en el período: la línea principal se concentra en 30 h o menos por semana, la mediana de cargos por médico se mantuvo en 2 (≈ 73 % con dos o más), sin tendencia. Como las horas son estables, ajustar por jornada no cambia la trayectoria, sólo el nivel.
  • Por hora, el cargo médico base vale 3.4 salarios mínimos en 2016 y 3 en 2025 (con jornada de 30 h): la relación se redujo -12% (2016→2025), y llegó a caer -19% hasta el piso de 2024.
  • Es prácticamente la misma caída que en la medición mensual (-12%), como era de esperar con horas constantes.
  • La corrección por jornada sube el nivel (de ~1,9 a ~3 mínimos por hora en 2025): comparar el cargo médico mensual con el SMM mensual mezcla una jornada parcial con una plena. Pero no revierte el signo: medido como se mida, el poder de compra de una hora médica respecto del mínimo se deterioró.

5.4 Comparación con el resto del MSPBS

Cambio real 2016→2025 por grupo
grupo y_ini y_fin cambio real
Médicos/as 12.738.887 9.454.470 -25.8%
Resto del MSPBS 5.062.877 4.085.919 -19.3%

Ambos grupos pierden poder adquisitivo: el congelamiento salarial del sector público no es exclusivo de los médicos, aunque ellos parten de un nivel más alto y la caída relativa es similar.

5.5 H3 — ¿Cuánto cuesta llevar el piso a ₲ 8.000.000?

Costo del ajuste del piso médico (13 pagos, TC 7300 ₲/USD). Nómina MSPBS.
Escenario Médicos alcanzados Costo anual (₲) Costo anual (USD)
A · brecha fija ₲3,0 M × todos los médicos (criterio Sinamed) 11.702 456.378.000.000 62.517.534
B · subir sólo a los que están bajo ₲8,0 M, por su brecha real 7.769 328.204.523.634 44.959.524
  • Con los ~11.702 médicos-persona del MSPBS en la nómina 2025, el criterio del Sinamed (brecha fija de ₲ 3,0 M) cuesta ≈ USD 63 millones/año; el criterio más acotado, ≈ USD 45 millones/año.
  • El gremio menciona USD 120 millones/año: ~2 veces la estimación con la nómina del MSPBS. La diferencia se explica porque la cifra gremial abarca a todos los médicos del sector público (MSPBS + IPS + universidades + municipios ≈ 20–25 mil, no sólo los 11.702 del MSPBS), e incluye cargas sociales y el arrastre de la escala. A escala nacional, USD 120 M es plausible; atribuido sólo al MSPBS, está sobreestimado.
  • Referencia: la masa salarial anualizada del MSPBS en 2025 fue ≈ ₲ 4.167 mil millones (USD 571 M/año). El escenario A equivale a 11.0% de esa masa.

5.6 H4 — ¿“Se paga solo”? Punto de equilibrio del argumento de inversión

La nómina no registra traslados ni complicaciones, de modo que no se puede demostrar que el ajuste se autofinancie. Sí se puede dar vuelta la pregunta: ¿cuánto tendría que ahorrar el Estado, por médico y por año, para cubrir el costo del ajuste?

## Costo incremental por médico/año: ₲ 39.000.000 ≈ USD 5342
  • El ajuste cuesta ₲ 39.000.000 (≈ USD 5342) por médico/año.
  • Para que “se pague solo”, cada médico debería evitar ese monto en gasto que hoy el Estado igual desembolsa: traslados en ambulancia o aéreos, derivaciones a privados, internaciones prolongadas por consultas tardías, cobertura de terapia intensiva, etc.
  • Órdenes de magnitud habituales: un traslado aéreo sanitario ≈ USD 3.000–8.000; un día de terapia intensiva ≈ USD 300–800. Bastaría que cada médico evitara ~1 traslado aéreo al año, o ~15–20 días-cama de UTI, para neutralizar fiscalmente el ajuste.

Esto no prueba la tesis del Sinamed, pero muestra que el umbral de ahorro necesario es bajo frente a los costos unitarios de la no-atención. La plausibilidad del argumento depende de evidencia clínica y de gestión que excede a la nómina.

6 Proyección a 10 años: ¿qué pasa si no hay ajustes?

Hasta acá se describió lo ocurrido 2016–2025. Esta sección lo proyecta hacia 2035 para responder la pregunta que está detrás del conflicto: si el salario médico sigue sin indexarse, ¿dónde termina su poder adquisitivo?

Mecánica y supuestos (todos en el chunk parametros):

  • Se parte de la remuneración mediana de 2025 (año con datos completos).
  • Inflación: tres sendas constantes — 3 % (baja), 4 % (central, ≈ meta del BCP) y 6 % (alta) anual.
  • Salario Mínimo: por la Ley 5764/16 se reajusta cada año por el IPC, así que en la proyección el SMM siempre sigue a la inflación. El salario público, en cambio, no tiene indexación automática: ese es el corazón del problema.
  • Política salarial médica 2026–2035: tres escenarios según qué fracción de la inflación se reconoce como aumento nominal — 0 % (congelamiento), 50 % (ajuste parcial) y 100 % (ajuste pleno, mantiene el poder adquisitivo, sirve de referencia).

6.1 Poder adquisitivo proyectado

Proyección a 2035 con inflación central (4 %/año). ‘No percibido’ = diferencia acumulada frente a indexar por IPC, 13 pagos/año, ₲ de 2025.
Política 2026–2035 Salario real 2035 (₲ 2025) Pérdida vs. 2025 Pérdida acum. vs. 2016 Cargo ppal. en SMM (2035) ₲ no percibidos por médico en 10 años
Congelamiento (0 % nominal) 6.141.493 -32.4% -49.9% 1.27 223.257.794
Ajuste parcial (50 % del IPC) 7.486.446 -17.6% -38.9% 1.55 118.058.514
Ajuste pleno = IPC (mantiene) 9.090.910 0.0% -25.8% 1.88 0
Escenario de congelamiento — sensibilidad a la inflación
Inflación anual Salario real 2035 (₲ 2025) Pérdida vs. 2025 Pérdida acum. vs. 2016 ₲ no percibidos / médico (10 años)
6 % 5.076.317 -44.2% -58.6% 311.989.743
3 % 6.764.491 -25.6% -44.8% 173.703.318
4 % 6.141.493 -32.4% -49.9% 223.257.794

6.2 Lectura de la proyección

  • Con congelamiento e inflación central (4 %), hacia 2035 la remuneración mediana real de un médico caería otro -32% frente al nivel de 2025. Sumada a la pérdida ya acumulada desde 2016, la caída total llega a -50%: prácticamente la mitad del poder adquisitivo que tenía en 2016.
  • El resultado es sensible a la inflación, pero el signo no cambia: la pérdida a 2035 (vs. 2016) va de -45% con inflación de 3 % a -59% con 6 %.
  • Un ajuste parcial del 50 % del IPC no alcanza: sólo frena a la mitad la caída (pérdida a 2035 de -18% vs. 2025, en lugar de -32%). Únicamente el ajuste pleno = IPC estabiliza el poder adquisitivo (por definición).
  • Lo que cada médico deja de percibir en 10 años por no indexar, en ₲ de 2025: ≈ ₲ 223.257.794 con inflación central (rango ₲ 173.703.318 – ₲ 311.989.743). Para el conjunto de 11.702 médicos del MSPBS son ≈ ₲ 2.613 mil millones (USD 358 millones) transferidos fuera del bolsillo médico en la década.
  • Contra el Salario Mínimo: como el SMM se indexa por ley y el sueldo médico no, la brecha se abre sola. Bajo congelamiento, el sueldo de un cargo médico (hoy ≈ 1.88 SMM) equivaldría a 1 solo salario mínimo hacia 2041 (entre 2036 con inflación alta y 2046 con inflación baja).

Qué es y qué no es esta proyección. Es un ejercicio determinístico de “si todo lo demás sigue igual”: inflación constante, sin cambios de escala, sin promociones ni antigüedad, sin nuevas guardias. No predice el futuro; cuantifica el costo de no hacer nada y sirve para comparar políticas de ajuste.

7 Calidad de los datos y limitaciones

  • Sólo julio y sólo MSPBS. No se ven IPS, universidades ni gobernaciones/municipios, donde también hay médicos. Las conclusiones aplican al MSPBS.
  • 2026 preliminar (planilla incompleta): se excluye de las conclusiones.
  • profesion incompleta antes de 2017; se mitiga con el panel “médico/a alguna vez”, pero el conteo de médicos de 2016 puede quedar algo subestimado.
  • “Remuneración” = devengado sumado. Incluye guardias, bonificaciones y aguinaldo si cayeron en julio; puede sobrestimar el “sueldo” mensual típico. Por eso se reporta también el cargo principal (línea de mayor monto).
  • No se depura por carga horaria (20 h vs 40 h) ni por doble cargo: un médico con dos nombramientos aparece con la suma de ambos.
  • IPC 2026 y tipo de cambio son supuestos (parámetros del documento).
  • La afirmación de base 2012 del Sinamed no es verificable con SFP (serie desde 2016).
  • La proyección (§6) es determinística, no un pronóstico: supone inflación constante, SMM indexado por la Ley 5764/16, y ninguna promoción, antigüedad ni cambio de escala. Sólo dimensiona el costo de no ajustar y compara políticas.

8 Conclusión

Síntesis del contraste
Afirmación Veredicto Evidencia principal
H1 · Salario médico congelado / se atrasó RESPALDADA (2016–2025) Real mediano -25.8% (2016→2025); cohorte fija -9.0%
H2 · Cayó de ~2,8 a ~1,5 salarios mínimos RESPALDADA en dirección y magnitud; el ‘1,5’ exacto depende de la base 2012 Cargo: 2.1→1.9 SMM/mes; por hora 3.4→3.0 SMM (-12%). Total: 4.3→3.1 SMM
H3 · Pasar de ₲5 M a ₲8 M cuesta ~USD 120 M/año PLAUSIBLE a escala nacional; SOBREESTIMADA si se atribuye sólo al MSPBS (~USD 55–65 M) 11.702 médicos MSPBS × ₲3 M × 13 pagos = USD 63 M
H4 · El ajuste ‘es una inversión’ (se paga solo) NO DEMOSTRABLE con la nómina; el punto de equilibrio requerido es bajo USD 5342/médico/año ≈ 1 traslado aéreo o ~15–20 días de UTI

Lo que los datos sostienen. La remuneración real de los médicos del MSPBS se deterioró de forma clara entre 2016 y 2025 —del orden de un 26% en la mediana, y 9% incluso para quienes no se movieron— y su salario medido en mínimos bajó de manera sostenida, tanto por mes como por hora (-12% para el cargo base, con jornada constante). En eso, el reclamo del Sinamed (H1, H2) está bien fundado.

Lo que conviene matizar. El costo del pedido para el MSPBS ronda los USD 55–65 millones/año, no 120; la cifra mayor sólo cierra si se suma a todo el sector público. Y la tesis central —que el ajuste “se paga solo” (H4)— no puede demostrarse con la nómina: es una hipótesis razonable (el ahorro necesario por médico es pequeño frente al costo de un traslado o una internación evitada), pero su prueba exige datos clínicos, de derivaciones y de traslados que el Estado debería poner sobre la mesa.

Mirando hacia adelante. La proyección (§6) muestra que no hacer nada no es un escenario neutro: como el Salario Mínimo se indexa por ley y el sueldo público no, mantener el congelamiento llevaría la pérdida acumulada de poder adquisitivo a ≈ -50% hacia 2035 (inflación central), y cada médico dejaría de percibir ≈ ₲ 223.257.794 en la década frente a un salario indexado. Un ajuste parcial (50 % del IPC) sólo frena la caída a la mitad.

En síntesis: los datos confirman que hay un problema salarial real y medible —pasado y, de mantenerse el congelamiento, agravado a futuro—; convertir el ajuste en una “inversión” que se autofinancia es plausible pero queda como afirmación por verificar, no como hecho establecido.


Reproducible con R ≥ 4.4, paquetes data.table, fst, ggplot2, scales. Series externas y parámetros en los chunks parametros y series_externas. Fuente de la nómina: Secretaría de la Función Pública del Paraguay.

9 Anexo · Script completo

El cuerpo del informe se compila sin mostrar código. El bloque siguiente reúne, en el orden en que se ejecutan, todos los fragmentos de R del documento (incluidos los parámetros y las series externas). No se evalúa aquí: sólo se transcribe para revisión y reproducción.

# Al compilar NO se muestra ningún código; el script completo va en el Anexo final.
knitr::opts_chunk$set(echo = FALSE, message = FALSE, warning = FALSE,
                      fig.width = 9, fig.height = 5, dpi = 110)
options(scipen = 999)
## --- Parámetros y supuestos (todos editables) ---------------------------------
ruta        <- "G:/Mi unidad/FACEN_BIGDATA/FACEN_BIG_DATA_2DO_SEM_2026/FACEN_BIG_DATA_2DO_SEM_2026/datos_funcion_publica_py/"
anio_base   <- 2026        # año al que se llevan los guaraníes constantes
piso_actual <- 5000000     # ₲ salario médico "actual" citado por el Sinamed
piso_pedido <- 8000000     # ₲ salario médico solicitado
pagos_anio  <- 13          # 12 sueldos + aguinaldo
gs_por_usd  <- 7300        # tipo de cambio de referencia (jul-2026 aprox.)
ipc_2026    <- 197.90      # PROYECCIÓN del IPC prom. 2026 (≈ +4 % sobre 2025)
anios_analisis <- 2016:2025 # 2026 se muestra aparte: descarga preliminar (ver §Calidad)

## --- Carga horaria para el indicador "costo hora" (§ H2 bis) ------------------
hrs_smm_sem      <- 48     # jornada plena de referencia del SMM (Cód. Laboral art. 194)
hrs_med_base_sem <- 30     # jornada del cargo médico base ("L a V 07:00–13:00"); sens. 24–40

## --- Parámetros de la proyección a futuro (§6) --------------------------------
h_proy   <- 10             # años proyectados hacia adelante (t0 = 2025 -> 2035)
anio_t0  <- 2025           # año base de la proyección (último con datos completos)
ipc_esc  <- c(baja = 0.03, central = 0.04, alta = 0.06)   # inflación anual supuesta
# Política salarial 2026–2035: fracción del IPC que se reconoce como ajuste nominal.
pol_esc  <- c("Congelamiento (0 % nominal)"        = 0.00,
              "Ajuste parcial (50 % del IPC)"      = 0.50,
              "Ajuste pleno = IPC (mantiene)"      = 1.00)
library(data.table)
library(fst)
library(ggplot2)
library(scales)
knitr::opts_chunk$set()
theme_set(theme_minimal(base_size = 12))
gs <- function(x) paste0("₲ ", format(round(x), big.mark = ".", decimal.mark = ","))
externas <- data.table(
  anho = 2016:2026,
  # SMM vigente en julio de cada año (₲). 2020 sin reajuste por pandemia.
  smm  = c(1964507, 2041123, 2112562, 2192839, 2192839,
           2289324, 2550307, 2680373, 2798309, 2899048, 3044000),
  # IPC promedio anual, base 2010 = 100 (Banco Mundial FP.CPI.TOTL; 2026 proyectado).
  ipc  = c(129.93, 134.61, 139.96, 143.82, 146.36,
           153.37, 168.35, 176.15, 182.90, 190.29, ipc_2026)
)
ipc_base <- externas[anho == anio_base, ipc]
externas[, deflactor := ipc_base / ipc]     # multiplica ₲ corrientes -> ₲ de anio_base
knitr::kable(externas, digits = 2,
             caption = "Salario Mínimo e IPC usados como referencia")
fps <- as.data.table(read_fst(paste0(ruta, "fpsalud_filtrada.fst")))

# La SFP publica en codificación latin1: normalizamos a UTF-8 para poder usar regex.
cols_chr <- names(fps)[vapply(fps, is.character, logical(1))]
for (cc in cols_chr) set(fps, j = cc, value = iconv(fps[[cc]], "latin1", "UTF-8"))

# Sólo julio, filas con pago efectivo (devengado > 0 descarta vacancias y no pagados).
fps <- fps[mes == 7 & devengado > 0]
cat("Filas con pago (julio, todas las entidades = MSPBS):", format(nrow(fps), big.mark = "."), "\n")
cat("Años disponibles:", paste(sort(unique(fps$anho)), collapse = ", "), "\n")
rx_med <- "MEDIC|CIRUJAN|DOCTOR EN MEDICINA|DOCTOR A EN MEDICINA|DOCTORA EN MEDICINA"
blob   <- toupper(paste(fps$profesion, fps$cargo, fps$funcion))
fps[, fila_medico := grepl(rx_med, blob) & !grepl("VETERINARI|ESTUDIANTE", blob)]

docs_medicos <- fps[fila_medico == TRUE, unique(documento)]
fps[, medico := documento %in% docs_medicos]

# Remuneración individual por año: total (suma de todas las líneas) y
# "cargo principal" (línea de mayor monto ≈ el sueldo del puesto).
pers <- fps[, .(
  sal_total     = sum(devengado),
  sal_principal = max(devengado),
  n_lineas      = .N,
  medico        = any(medico)
), by = .(documento, anho)]

pers <- merge(pers, externas[, .(anho, smm, ipc, deflactor)], by = "anho")
pers[, sal_total_real     := sal_total     * deflactor]
pers[, sal_principal_real := sal_principal * deflactor]
pers[, sal_total_smm      := sal_total     / smm]
pers[, sal_principal_smm  := sal_principal / smm]

med <- pers[medico == TRUE]
knitr::kable(
  med[, .(medicos = .N,
          `% con >1 línea` = round(100 * mean(n_lineas > 1)),
          principal_mediana = round(median(sal_principal)),
          total_mediana     = round(median(sal_total))),
      by = anho][order(anho)],
  format.args = list(big.mark = "."),
  caption = "Panel de médicos/as del MSPBS (julio de cada año)"
)
parse_week_hours <- function(x) {
  s <- toupper(x)
  s <- chartr("ÁÉÍÓÚÜÑ", "AEIOUUN", s)
  s <- gsub("HRS?\\b|\\bHS?\\b|HORAS?", " ", s)
  s <- gsub("\\(A\\)", " A ", s); s <- gsub("[.,;]", " ", s); s <- gsub(":", " ", s)
  s <- gsub("\\s+", " ", trimws(s))
  if (is.na(s) || s == "" || s == "0") return(NA_real_)
  mult <- NA_real_
  if (grepl("LUNES A VIERNES|LUN A VIE", s))                    mult <- 5
  if (grepl("LUNES A SABADO", s))                               mult <- 6
  if (grepl("LUNES A DOMINGO|DIARIO|TODOS LOS DIAS", s))        mult <- 7
  if (grepl("SABADO.? Y DOMINGO|SABADO.? DOMINGO|FIN(ES)? DE SEMANA", s)) mult <- 2
  if (is.na(mult)) {
    dias <- c("LUNES","MARTES","MIERCOLES","JUEVES","VIERNES","SABADO","DOMINGO")
    nd <- sum(vapply(dias, function(z) grepl(z, s), logical(1)))
    mult <- if (nd > 0) nd else 5
  }
  m <- regmatches(s, regexec("(\\d{1,2})(?: (\\d{2}))? A (\\d{1,2})(?: (\\d{2}))?", s))[[1]]
  daily <- NA_real_
  if (length(m) == 5) {
    h1 <- as.numeric(m[2]); mi1 <- ifelse(m[3] == "", 0, as.numeric(m[3])) / 60
    h2 <- as.numeric(m[4]); mi2 <- ifelse(m[5] == "", 0, as.numeric(m[5])) / 60
    dur <- (h2 + mi2) - (h1 + mi1)
    if (!is.na(dur) && dur <= 0) dur <- dur + 24
    if (!is.na(dur) && dur > 0 && dur <= 16) daily <- dur
  }
  base <- if (!is.na(daily)) daily * mult else NA_real_
  extra <- 0
  gg <- regmatches(s, gregexpr("GUARDIA[A-Z ]*? DE (\\d{1,2})", s))[[1]]
  if (length(gg)) {
    hrsg <- as.numeric(sub(".*DE ", "", gg)); nrep <- 1
    if (grepl("DOS GUARDIA", s))  nrep <- 2
    if (grepl("TRES GUARDIA", s)) nrep <- 3
    extra <- sum(hrsg, na.rm = TRUE) * ifelse(length(gg) == 1, nrep, 1)
  }
  tot <- sum(base, extra, na.rm = TRUE)
  if (is.na(tot) || tot <= 0) return(NA_real_)
  min(tot, 90)
}

uh <- unique(fps$carga_horaria)
fps[, wk_sem := setNames(vapply(uh, parse_week_hours, numeric(1)), uh)[carga_horaria]]

# Horas de la línea de mayor monto (≈ el cargo principal), por persona-año
pers_h <- fps[, .(wk_ppal = wk_sem[which.max(devengado)]), by = .(documento, anho)]
pers <- merge(pers, pers_h, by = c("documento", "anho"), all.x = TRUE)
med  <- pers[medico == TRUE]

cobertura_ch <- fps[, .(cobertura = round(100 * mean(!is.na(wk_sem)))), by = anho][order(anho)]
resumen <- med[, .(
  principal_nom  = median(sal_principal),
  total_nom      = median(sal_total),
  principal_real = median(sal_principal_real),
  total_real     = median(sal_total_real),
  total_smm      = median(sal_total_smm),
  principal_smm  = median(sal_principal_smm)
), by = anho][order(anho)]
knitr::kable(resumen, digits = 2, format.args = list(big.mark = "."),
             caption = paste0("Remuneración mensual mediana de médicos/as del MSPBS. ",
                              "Valores reales en ₲ de ", anio_base, "."))

d1 <- melt(resumen[, .(anho, `Nominal` = total_nom,
                       `Real (₲ 2026)` = total_real)],
           id.vars = "anho")
ggplot(d1, aes(anho, value, color = variable)) +
  geom_line(aes(linetype = anho > max(anios_analisis)), linewidth = 1) +
  geom_point(data = d1[anho %in% anios_analisis], size = 2) +
  scale_y_continuous(labels = label_number(big.mark = ".", prefix = "₲ ")) +
  scale_x_continuous(breaks = 2016:2026) +
  scale_linetype_manual(values = c("solid", "dotted"), guide = "none") +
  labs(title = "Remuneración mensual TOTAL mediana de un médico/a del MSPBS",
       subtitle = "Suma de todas las líneas de pago. 2026 preliminar (punteado).",
       x = NULL, y = NULL, color = NULL)
r16 <- resumen[anho == 2016]; r25 <- resumen[anho == 2025]
cambio_nom  <- r25$total_nom  / r16$total_nom  - 1
cambio_real <- r25$total_real / r16$total_real - 1
ipc_16_25   <- externas[anho == 2025, ipc] / externas[anho == 2016, ipc] - 1
c17 <- pers[medico == TRUE & anho == 2017, .(documento, s17 = sal_total_real)]
c25 <- pers[medico == TRUE & anho == 2025, .(documento, s25 = sal_total_real)]
coh <- merge(c17, c25, by = "documento")
cambio_coh <- median(coh$s25 / coh$s17) - 1
cat("Médicos presentes en 2017 y 2025:", nrow(coh), "\n")
cat("Cambio real mediano de su remuneración 2017→2025:", percent(cambio_coh, 0.1), "\n")
cat("Proporción que perdió poder adquisitivo:", percent(mean(coh$s25 < coh$s17), 0.1), "\n")
d2 <- melt(resumen[, .(anho,
                       `Total / SMM` = total_smm,
                       `Cargo principal / SMM` = principal_smm)],
           id.vars = "anho")
ggplot(d2, aes(anho, value, color = variable)) +
  geom_line(aes(linetype = anho > max(anios_analisis)), linewidth = 1) +
  geom_point(data = d2[anho %in% anios_analisis], size = 2) +
  geom_hline(yintercept = c(1.5, 2.8), linetype = "dashed", color = "grey50") +
  annotate("text", x = 2016.2, y = 2.9, label = "2,8 SMM (Sinamed, 2012)", hjust = 0, size = 3) +
  annotate("text", x = 2016.2, y = 1.6, label = "1,5 SMM (Sinamed, 2026)", hjust = 0, size = 3) +
  scale_x_continuous(breaks = 2016:2026) +
  scale_linetype_manual(values = c("solid", "dotted"), guide = "none") +
  labs(title = "Remuneración médica expresada en Salarios Mínimos Mensuales (SMM)",
       x = NULL, y = "Cantidad de SMM", color = NULL)

smm_16_26 <- externas[anho == 2026, smm] / externas[anho == 2016, smm] - 1
# ¿Cambió la jornada del cargo médico? (años con cobertura decente del campo)
jbin <- med[!is.na(wk_ppal) & anho %in% 2021:2025]
jbin[, tramo := cut(wk_ppal, c(-Inf, 20, 30, 40, Inf),
                    labels = c("≤20 h", "21–30 h", "31–40 h", ">40 h"))]
tj <- dcast(jbin, anho ~ tramo, fun.aggregate = length, value.var = "wk_ppal")
num <- setdiff(names(tj), "anho")
tot <- rowSums(tj[, ..num])
tj[, (num) := lapply(.SD, function(x) round(100 * x / tot)), .SDcols = num]
tj <- merge(tj, cobertura_ch, by = "anho")
setnames(tj, c("anho", "cobertura"), c("Año", "cobertura del campo (%)"))
knitr::kable(tj, caption = paste0("Jornada semanal de la línea principal de los médicos, ",
  "distribución en % (años con buena cobertura del campo)."))

lineas_med <- med[, .(`líneas de pago (mediana)` = as.numeric(median(n_lineas)),
                      `% con ≥2 líneas` = round(100 * mean(n_lineas >= 2))),
                  by = anho][order(anho)]
setnames(lineas_med, "anho", "Año")
knitr::kable(lineas_med, caption = "Número de cargos / líneas de pago por médico y año")
mes_h_med <- hrs_med_base_sem * 52 / 12
mes_h_smm <- hrs_smm_sem     * 52 / 12

ratio_h <- med[, .(
  ratio_mensual = median(sal_principal / smm),
  ratio_hora    = median((sal_principal / mes_h_med) / (smm / mes_h_smm)),
  # sensibilidad: jornada médica de 24 y 40 h
  ratio_hora_24 = median((sal_principal / (24 * 52/12)) / (smm / mes_h_smm)),
  ratio_hora_40 = median((sal_principal / (40 * 52/12)) / (smm / mes_h_smm))
), by = anho][order(anho)]

knitr::kable(ratio_h[anho %in% anios_analisis], digits = 2,
  col.names = c("Año", "Ratio mensual (cargo/SMM)",
                paste0("Ratio hora (", hrs_med_base_sem, " h)"),
                "Ratio hora (sens. 24 h)", "Ratio hora (sens. 40 h)"),
  caption = paste0("Suficiencia del cargo médico frente al Salario Mínimo: por mes vs. ",
                   "por hora. Jornada médica base = ", hrs_med_base_sem,
                   " h/sem; SMM = ", hrs_smm_sem, " h/sem."))

d2b <- melt(ratio_h[anho %in% anios_analisis,
                    .(anho, `Por mes (cargo / SMM)` = ratio_mensual,
                      `Por hora (misma jornada)` = ratio_hora)],
            id.vars = "anho")
ggplot(d2b, aes(anho, value, colour = variable)) +
  geom_line(linewidth = 1) + geom_point(size = 2) +
  geom_hline(yintercept = 1, linetype = "dotted", colour = "grey55") +
  scale_x_continuous(breaks = anios_analisis) +
  expand_limits(y = 0) +
  labs(title = "¿Cuántos 'mínimos' vale el cargo médico? Por mes y por hora",
       subtitle = paste0("Cargo médico base ", hrs_med_base_sem,
                          " h/sem vs. SMM ", hrs_smm_sem, " h/sem"),
       x = NULL, y = "Salarios mínimos equivalentes", colour = NULL)

rh16 <- ratio_h[anho == 2016]; rh25 <- ratio_h[anho == 2025]; rh24 <- ratio_h[anho == 2024]
chg_mes  <- rh25$ratio_mensual / rh16$ratio_mensual - 1
chg_hora <- rh25$ratio_hora    / rh16$ratio_hora    - 1
chg_hora_min <- rh24$ratio_hora / rh16$ratio_hora   - 1
comp <- pers[, .(mediana_real = median(sal_total_real)),
             by = .(anho, grupo = fifelse(medico, "Médicos/as", "Resto del MSPBS"))]
ggplot(comp[anho %in% anios_analisis], aes(anho, mediana_real, color = grupo)) +
  geom_line(linewidth = 1) + geom_point(size = 2) +
  scale_y_continuous(labels = label_number(big.mark = ".", prefix = "₲ ")) +
  scale_x_continuous(breaks = anios_analisis) +
  labs(title = "Remuneración total mediana real: médicos vs. resto del MSPBS",
       subtitle = paste0("₲ constantes de ", anio_base),
       x = NULL, y = NULL, color = NULL)

tab_comp <- dcast(comp[anho %in% range(anios_analisis)], grupo ~ anho,
                  value.var = "mediana_real")
setnames(tab_comp, as.character(range(anios_analisis)), c("y_ini", "y_fin"))
tab_comp[, `cambio real` := percent(y_fin / y_ini - 1, 0.1)]
knitr::kable(tab_comp, format.args = list(big.mark = "."),
             caption = "Cambio real 2016→2025 por grupo")
n_med_2025    <- med[anho == 2025, .N]
# Médicos cuyo cargo principal hoy está por debajo del piso pedido:
bajo_piso     <- med[anho == 2025 & sal_principal < piso_pedido]
n_bajo_piso   <- nrow(bajo_piso)
brecha_media  <- mean(piso_pedido - bajo_piso$sal_principal)

# Escenario A (Sinamed): brecha fija de ₲3.000.000 para todos los médicos.
costo_A_gs  <- n_med_2025 * (piso_pedido - piso_actual) * pagos_anio
# Escenario B (nómina): subir sólo a quienes están por debajo del piso, su brecha real.
costo_B_gs  <- n_bajo_piso * brecha_media * pagos_anio

esc <- data.table(
  Escenario = c("A · brecha fija ₲3,0 M × todos los médicos (criterio Sinamed)",
                "B · subir sólo a los que están bajo ₲8,0 M, por su brecha real"),
  `Médicos alcanzados` = c(n_med_2025, n_bajo_piso),
  `Costo anual (₲)`   = c(costo_A_gs, costo_B_gs),
  `Costo anual (USD)` = c(costo_A_gs, costo_B_gs) / gs_por_usd
)
knitr::kable(esc, digits = 0, format.args = list(big.mark = "."),
             caption = paste0("Costo del ajuste del piso médico (", pagos_anio,
                              " pagos, TC ", gs_por_usd, " ₲/USD). Nómina MSPBS."))

masa_2025_gs <- fps[anho == 2025, sum(as.numeric(devengado))] * pagos_anio
costo_por_medico_anio_gs  <- (piso_pedido - piso_actual) * pagos_anio      # ₲3,0M × 13
costo_por_medico_anio_usd <- costo_por_medico_anio_gs / gs_por_usd
cat("Costo incremental por médico/año:",
    gs(costo_por_medico_anio_gs), "≈ USD", round(costo_por_medico_anio_usd), "\n")
base_p  <- resumen[anho == anio_t0]
p0_total     <- base_p$total_nom
p0_principal <- base_p$principal_nom
smm0         <- externas[anho == anio_t0, smm]

# Grilla inflación × política × horizonte
proy <- CJ(infl = names(ipc_esc), pol = names(pol_esc), t = 0:h_proy)
proy[, `:=`(ipc = ipc_esc[infl], frac = pol_esc[pol], anho = anio_t0 + t)]

proy[, sal_total_nom     := p0_total     * (1 + frac * ipc)^t]
proy[, sal_principal_nom := p0_principal * (1 + frac * ipc)^t]
proy[, smm               := smm0 * (1 + ipc)^t]                 # SMM indexado por ley
proy[, sal_total_real     := sal_total_nom     / (1 + ipc)^t]   # ₲ constantes de 2025
proy[, sal_principal_real := sal_principal_nom / (1 + ipc)^t]
proy[, total_smm     := sal_total_nom     / smm]
proy[, principal_smm := sal_principal_nom / smm]

# Histórico re-expresado en ₲ de 2025 para empalmar con la proyección
hist25 <- merge(resumen[anho <= anio_t0, .(anho, total_nom, principal_nom)],
                externas[, .(anho, ipc)], by = "anho")
ipc25 <- externas[anho == anio_t0, ipc]
hist25[, `:=`(sal_total_real     = total_nom     * ipc25 / ipc,
              sal_principal_real = principal_nom * ipc25 / ipc)]

# Ingreso NO percibido en 10 años vs. mantener el poder adquisitivo (₲ de 2025)
ref <- proy[pol == "Ajuste pleno = IPC (mantiene)", .(infl, t, ref_real = sal_total_real)]
proy <- merge(proy, ref, by = c("infl", "t"))
no_perc <- proy[t >= 1, .(no_percibido = sum(ref_real - sal_total_real) * pagos_anio),
                by = .(infl, pol)]
gc <- proy[infl == "central"]
ggplot() +
  geom_line(data = hist25, aes(anho, sal_total_real), linewidth = 1) +
  geom_point(data = hist25, aes(anho, sal_total_real), size = 1.5) +
  geom_line(data = gc, aes(anho, sal_total_real, color = pol),
            linewidth = 1, linetype = "22") +
  geom_hline(yintercept = p0_total, linetype = "dotted", colour = "grey55") +
  annotate("text", x = 2016, y = p0_total * 1.02, hjust = 0, size = 3,
           label = "nivel de 2025") +
  scale_y_continuous(labels = label_number(big.mark = ".", prefix = "₲ "),
                     limits = c(0, NA)) +
  scale_x_continuous(breaks = seq(2016, 2035, 3)) +
  labs(title = "Poder adquisitivo del salario médico: histórico (2016–2025) y proyección (2026–2035)",
       subtitle = paste0("Remuneración total mediana, ₲ constantes de ", anio_t0,
                          ". Inflación central 4 %/año."),
       x = NULL, y = NULL, colour = "Política 2026–2035")
banda <- dcast(proy[pol == "Congelamiento (0 % nominal)"],
               anho ~ infl, value.var = "sal_total_real")
ggplot(banda, aes(anho)) +
  geom_line(data = hist25, aes(anho, sal_total_real), linewidth = 1) +
  geom_ribbon(aes(ymin = alta, ymax = baja), alpha = .18, fill = "firebrick") +
  geom_line(aes(y = central), colour = "firebrick", linewidth = 1, linetype = "22") +
  geom_hline(yintercept = p0_total, linetype = "dotted", colour = "grey55") +
  scale_y_continuous(labels = label_number(big.mark = ".", prefix = "₲ "),
                     limits = c(0, NA)) +
  scale_x_continuous(breaks = seq(2016, 2035, 3)) +
  labs(title = "Escenario de congelamiento: rango según la inflación (3 % – 6 %)",
       subtitle = paste0("Banda = inflación entre 3 % y 6 %; línea = 4 %. ₲ de ", anio_t0, "."),
       x = NULL, y = NULL)
fin <- proy[t == h_proy]
fin[, perdida_2025 := 1 - sal_total_real / p0_total]
fin[, infl := factor(infl, levels = c("baja", "central", "alta"),
                     labels = c("3 %", "4 %", "6 %"))]
ggplot(fin, aes(reorder(pol, -perdida_2025), perdida_2025, fill = infl)) +
  geom_col(position = position_dodge(.85), width = .8) +
  geom_text(aes(label = percent(perdida_2025, 1)),
            position = position_dodge(.85), vjust = -0.35, size = 3) +
  scale_y_continuous(labels = percent, expand = expansion(c(0, .15))) +
  scale_fill_brewer(palette = "OrRd") +
  labs(title = "Pérdida de poder adquisitivo acumulada a 2035 (vs. 2025)",
       x = NULL, y = NULL, fill = "Inflación anual") +
  theme(axis.text.x = element_text(size = 9))
fin2 <- proy[t == h_proy]
fin2[, perdida_2025 := 1 - sal_total_real / p0_total]
fin2[, perdida_2016 := 1 - sal_total_real / hist25[anho == 2016, sal_total_real]]
tab <- merge(fin2, no_perc, by = c("infl", "pol"))
tab_c <- tab[infl == "central"][order(-perdida_2025)]
knitr::kable(
  tab_c[, .(`Política 2026–2035` = pol,
            `Salario real 2035 (₲ 2025)` = round(sal_total_real),
            `Pérdida vs. 2025` = percent(-perdida_2025, 0.1),
            `Pérdida acum. vs. 2016` = percent(-perdida_2016, 0.1),
            `Cargo ppal. en SMM (2035)` = round(principal_smm, 2),
            `₲ no percibidos por médico en 10 años` = round(no_percibido))],
  format.args = list(big.mark = "."),
  caption = paste0("Proyección a 2035 con inflación central (4 %/año). ",
                   "'No percibido' = diferencia acumulada frente a indexar por IPC, ",
                   pagos_anio, " pagos/año, ₲ de ", anio_t0, "."))

# Sensibilidad del congelamiento a la inflación
sens <- tab[pol == "Congelamiento (0 % nominal)"][order(infl)]
knitr::kable(
  sens[, .(`Inflación anual` = c("3 %", "4 %", "6 %")[match(infl, c("baja","central","alta"))],
           `Salario real 2035 (₲ 2025)` = round(sal_total_real),
           `Pérdida vs. 2025` = percent(-perdida_2025, 0.1),
           `Pérdida acum. vs. 2016` = percent(-perdida_2016, 0.1),
           `₲ no percibidos / médico (10 años)` = round(no_percibido))],
  format.args = list(big.mark = "."),
  caption = "Escenario de congelamiento — sensibilidad a la inflación")
cc <- tab[pol == "Congelamiento (0 % nominal)" & infl == "central"]
clo <- tab[pol == "Congelamiento (0 % nominal)" & infl == "baja"]
chi <- tab[pol == "Congelamiento (0 % nominal)" & infl == "alta"]
parc <- tab[pol == "Ajuste parcial (50 % del IPC)" & infl == "central"]
# año en que el sueldo de un cargo médico equivaldría a 1 SMM (congelamiento)
t_1smm    <- log(p0_principal / smm0) / log(1 + ipc_esc)
anio_1smm <- round(anio_t0 + t_1smm)
agg_congel <- cc$no_percibido * n_med_2025
knitr::kable(data.table(
  Afirmación = c("H1 · Salario médico congelado / se atrasó",
                 "H2 · Cayó de ~2,8 a ~1,5 salarios mínimos",
                 "H3 · Pasar de ₲5 M a ₲8 M cuesta ~USD 120 M/año",
                 "H4 · El ajuste 'es una inversión' (se paga solo)"),
  Veredicto = c("RESPALDADA (2016–2025)",
                "RESPALDADA en dirección y magnitud; el '1,5' exacto depende de la base 2012",
                "PLAUSIBLE a escala nacional; SOBREESTIMADA si se atribuye sólo al MSPBS (~USD 55–65 M)",
                "NO DEMOSTRABLE con la nómina; el punto de equilibrio requerido es bajo"),
  `Evidencia principal` = c(
    sprintf("Real mediano %s (2016→2025); cohorte fija %s", percent(cambio_real,0.1), percent(cambio_coh,0.1)),
    sprintf("Cargo: %.1f→%.1f SMM/mes; por hora %.1f→%.1f SMM (%s). Total: %.1f→%.1f SMM",
            resumen[anho==2016]$principal_smm, resumen[anho==2025]$principal_smm,
            rh16$ratio_hora, rh25$ratio_hora, percent(chg_hora, 1),
            resumen[anho==2016]$total_smm, resumen[anho==2025]$total_smm),
    sprintf("%s médicos MSPBS × ₲3 M × %d pagos = USD %d M",
            format(n_med_2025, big.mark="."), pagos_anio, round(costo_A_gs/gs_por_usd/1e6)),
    sprintf("USD %d/médico/año ≈ 1 traslado aéreo o ~15–20 días de UTI",
            round(costo_por_medico_anio_usd)))
), caption = "Síntesis del contraste")