Explorando los datos de los presupuestos nacionales
Exploración de datos de presupuestos nacionales¶
En el post anterior mostré el scrape hecho al sistema de contabilidad del estado SICOIN. Ahora tomaré esos datos para explorarlos.
Una cosa que quiero mencionar antes, para quienes no estén familiarizados con estos datos es el significado del presupuesto asignado, vigente y devengado.
El dinero Asignado es lo que sale de la alcantarilla del congreso. Así como el presupuesto 2021 fue discutido entre varios sectores, cada ministerio solicitó ciertas cantidades para cada programa, renglón, etc, hay un presupuesto solicitado pero luego eso llega al deshonorable congreso de la república y allí entre los 160 diputados, negocian y reparten el dinero casi a su antojo. Claro que hay límites y no pueden en realidad tomar todo el dinero, digamos, para sus bonos. Pero sí negocian obras, empleo, plazas fantasma, aumentos, posiciones de poder en los ministerios, favores políticos, y quién sabe qué más. Aunque un ministerio solicite una cantidad, el congreso lo puede modificar. Del congreso sale, entonces, un presupuesto Asignado. Luego ya al momento de enfrentar la realidad tal asignación va quedando obsoleta y se hace necesario modificar los montos presupuestados. Hay una columna de Modificado y luego Asignado + Modificado = Vigente. Finalmente, se llega a lo Devengado, que es lo que sale de las cuentas del estado para pagar todo lo que se ha ido Ejecutando. No se llega a ejecutar todo, usualmente y siempre hay un excedente que queda para el próximo ciclo.
import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn
import altair
%matplotlib inline
datos = pd.read_csv("sicoin_programas_acts_2004-2020.csv.gz", index_col=0)
datos.columns
Presupuestos totales (Asignado, Vigente y Devengado) por año¶
#seaborn.lineplot(
plot = datos.groupby("Year").agg({
"Asignado": "sum",
"Vigente": "sum",
"Devengado": "sum"
}).plot()
plt.gca().yaxis.set_major_formatter(plt.matplotlib.ticker.FuncFormatter(lambda x, i: str(int(x/1e9))+"B"))
plt.grid(True)
En 2020 se dispara lo vigente por la emergencia del COVID-19 (aunque los beneficios no fueron pagados a la mayoría de la población) y hay poca ejecución (seguramente porque estos datos fueron obtenidos sin que finalice el año).
import re
import unicodedata
espacios = re.compile('\s+')
puntofinal = re.compile("\.\s*
quot;) pgnfinal = re.compile("\(PGN\)\s*
quot;) def remove_accents(input_str): try: nfkd_form = unicodedata.normalize('NFKD', input_str) only_ascii = nfkd_form.encode('ASCII', 'ignore') return str(only_ascii.decode()).strip() except: return ""
datos.CodEntidad.replace(espacios, " ").replace(puntofinal,"").replace(pgnfinal,"").apply(remove_accents)\
.apply(lambda x: x.split(" - ")[1]).value_counts()
datos["Entidad"] = datos.CodEntidad.replace(espacios, " ").replace(puntofinal,"").replace(pgnfinal,"").apply(remove_accents)\
.apply(lambda x: x.split(" - ")[1])
datosentidad = datos.groupby(["Entidad", "Year"]).agg({
"Asignado": "sum",
"Vigente": "sum",
"Devengado": "sum"
})
datosentidad.reset_index().columns
Heatmap logarítmico que muestra la concentración del dinero devengado¶
altair.Chart.from_dict(
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "A simple bar chart with embedded data.",
"data": {
"values": datosentidad.reset_index().to_dict(orient = "records")
},
"mark": "rect",
"encoding": {
"x": {
"field": "Year",
"type": "nominal"
},
"y": {
"field": "Entidad",
"type": "nominal"
},
"color": {
"aggregate": "sum", "field": "Devengado",
"type": "quantitative",
"scale": {
"type":"log",
"scheme": "viridis",
}
}
}
}
)
plotdata = datosentidad.reset_index().sort_values(["Devengado"],ascending=False).assign(Entidad = lambda x: \
x.Entidad.apply(lambda y : y.replace("MINISTERIO", "M.")\
.replace("SECRETARIA", "SEC.").replace("OBLIGACIONES", "OB."))).to_dict(orient = "records")
Intentando visualizar la distribución del presupuesto por año en un sólo gráfico es difícil porque hay entidades que apenas se notan y otras que abarcan cantidades inmensas. Por lo menos se puede observar que los mayores montos están en Obligaciones del estado a cargo del tesoro (aportes a municipalidades, congreso de la república, sistema de justicia, SAT y otras cosas), Servicios de la deuda pública (pago de deuda pública), Min. de Educación, Min. de Salud, Min. de comunicaciones, infraestructura y vivienda, Min. de gobernación (PNC, MP, etc), El ejército (Min. de defensa (¿defensa de qué?)).
Dinero devengado por Entidad (miles de millones)¶
campo = "Devengado"
altair.Chart.from_dict(
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "Chart",
"data": {
"values": plotdata
},
"layer":[
{
"mark": {"type": "bar", "tooltip": True},
"encoding": {
"tooltip": [
{"field": campo, "type": "quantitative", "title": campo, "format": ".2s"},
{"field": "Entidad", "type": "nominal", "title": "Entidad"},
],
#"order": {"field": campo, "type": "quantitative"
#},
"y": {
"field": campo,
"type": "quantitative",
"axis": {"format": ".2s", "title": campo},
# "scale": {"type": "pow", "exponent": 0.5,}
},
"x": {"field": "Year", "type": "nominal"},
"color": {
"field": "Entidad",
"type": "nominal",
"scale": {"scheme": "category20b"}
}
}
}
],
"width": 600
})
Porcentaje de presupuesto devengado por entidad:¶
campo = "Devengado"
altair.Chart.from_dict(
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "Chart",
"data": {
"values": plotdata
},
"layer":[
{
"mark": {"type": "bar", "tooltip": True},
"encoding": {
"order": {"field": campo, "type": "quantitative", "sort":"descending"
},
"y": {
"field": campo,
"type": "quantitative",
"stack": "normalize",
"axis": {"format": "%", "title": campo}
},
"x": {"field": "Year", "type": "nominal"},
"color": {
"field": "Entidad",
"type": "nominal",
"scale": {"scheme": "category20b"}
},
"tooltip": [
{"field": campo, "type": "quantitative", "title": campo, "format": ".2s"},
{"field": "Entidad", "type": "nominal", "title": "Entidad"},
],
}
}
],
"width": 600
})
Veamos la tendencia de cada entidad de 2004 a 2020 por separado para que la gran diferencia entre las cantidades no invisibilice a las entidades con menor presupuesto.
campo = "Devengado"
altair.Chart.from_dict(
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "Chart",
"data": {
"values": plotdata
},
"mark": {"type": "line", "tooltip": True},
"encoding": {
"facet": {"field": "Entidad", "type": "ordinal", "columns": 3},
"y": {
"field": campo,
"type": "quantitative",
"axis": {"format": ".2s", "title": campo}
},
"x": {"field": "Year", "type": "nominal"},
"tooltip": [
{"field": campo, "type": "quantitative", "title": campo, "format": ".2s"},
{"field": "Entidad", "type": "nominal", "title": "Entidad"},
],
},
"width": 200, "height": 50,
"resolve": {
"axis": {"y": "independent"},
"scale": {"y": "independent"},
},
"title": "Presupuestos por entidad por año"
})
temp = datosentidad.Devengado.unstack(level=0)
temp["total"] = temp.sum(axis=1)
temp = temp.divide(temp.total, axis="rows")
temp = temp.drop(columns="total").stack().rename("Devengado").reset_index().to_dict("records")
temp[0]
Y ahora las series temporales de porcentaje de cada entidad en el presupuesto devengado entre 2004-2020.
campo = "Devengado"
altair.Chart.from_dict(
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "Chart",
"data": {
"values": temp
},
"mark": {"type": "line", "tooltip": True},
"encoding": {
"facet": {"field": "Entidad", "type": "ordinal", "columns": 3},
"y": {
"field": campo,
"type": "quantitative",
"axis": {"format": "%", "title": campo}
},
"x": {"field": "Year", "type": "nominal"},
"tooltip": [
{"field": campo, "type": "quantitative", "title": campo, "format": ".2s"},
{"field": "Entidad", "type": "nominal", "title": "Entidad"},
],
},
"width": 250, "height": 50,
"resolve": {
"axis": {"y": "independent"},
"scale": {"y": "independent"},
},
"title": "Porcentaje por entidad cada año"
})
temp = datosentidad.Devengado.unstack(level=0)
temp["total"] = temp.sum(axis=1)
temp = temp.divide(temp.total, axis="rows")
temp = temp.drop(columns="total").stack().rename("Devengado").reset_index()\
[lambda x: x.Entidad.map(lambda y: "GOBERN" in y)].to_dict("records")
Las actividades más costosas en 2019 de la categoría “Oblicaciones del estado a cargo el tesoro” :¶
plotdata = datos[datos.Entidad.map(lambda x: "OBLIG" in x)].groupby(["Year","ActOb"]).agg({
"Devengado": "sum",
"Vigente": "sum",
"Asignado": "sum"
})
plotdata = plotdata[["Devengado"]].divide(1e6).round().unstack(0).reset_index().sort_values(("Devengado", 2019),ascending=False).head(20)
plotdata.fillna(0)
plotdata = datos[datos.Entidad.map(lambda x: "OBLIG" in x)].groupby(["Year","ActOb"]).agg({
"Devengado": "sum",
"Vigente": "sum",
"Asignado": "sum"
})
plotdata = plotdata[["Devengado"]].divide(1e6).round().unstack(0)#.reset_index().sort_values(("Devengado", 2020),ascending=False)
plotdata.divide(plotdata.sum()/100.0, axis="columns").round(2).fillna(0).sort_values(("Devengado", 2019), ascending= False).head(20)
Las actividades más costosas en 2004 de la categoría “Oblicaciones del estado a cargo el tesoro” :¶
plotdata = datos[datos.Entidad.map(lambda x: "OBLIG" in x)].groupby(["Year","ActOb"]).agg({
"Devengado": "sum",
"Vigente": "sum",
"Asignado": "sum"
})
plotdata = plotdata[["Devengado"]].divide(1e6).round().unstack(0).reset_index().sort_values(("Devengado", 2010),ascending=False).head(20)
plotdata.fillna(0)
plotdata = datos[datos.Entidad.map(lambda x: "OBLIG" in x)].groupby(["Year","ActOb"]).agg({
"Devengado": "sum",
"Vigente": "sum",
"Asignado": "sum"
})
plotdata = plotdata[["Devengado"]].divide(1e6).round().unstack(0)#.reset_index().sort_values(("Devengado", 2020),ascending=False)
plotdata.divide(plotdata.sum()/100.0, axis="columns").round(2).fillna(0).sort_values(("Devengado", 2004), ascending= False).head(20)
Hay varias cosas que resaltar de esto. Ver por ejemplo los costos de el fideicomiso para el transporte público, los gastos del RENAP, SAT (administración fiscal), congreso (admin/actividades legislativas) o el sistema de justicia.
defensa = datos[datos.CodEntidad.apply(lambda x: "defensa" in x.lower())]
Buscando las actividades del ejército que tengan que ver con la presencia de militares en las calles¶
temp = defensa[defensa.ActOb.apply(lambda x: "CIUDADANA" in x or "SEGURIDAD P" in x\
or "ESTADO DE SITIO" in x) | \
defensa.Programa.apply(lambda x: "DELI" in x or "HOMICIDIO" in x)
][["Programa", "ActOb", "Year", "Devengado"]]
for i, row in temp.sort_values("Year").iterrows():
print(str(row.Year) + "\n\tProg:" + row.Programa + "\n\tAct:" + row.ActOb + "\n\t\t\tQ " + str(round(row.Devengado/1e6,2))+ " M")
Estimado de gasto por presencia del ejército en las calles según Programa y Actividad del presupuesto¶
(temp.groupby("Year").Devengado.sum() / 1e6).round(2).plot()
plt.ylabel("Millones de Quetzales")
plt.xlabel("Año")
defensa["Programa"] = defensa["Programa"].apply(remove_accents)
Porcentaje de gasto del ejército por programa por año¶
campo = "Devengado"
grupo = "Programa"
altair.Chart.from_dict(
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
"description": "Chart",
"data": {
"values": defensa.groupby(["Year",grupo])[campo].sum().reset_index().to_dict("records")
},
"layer":[
{
"mark": {"type": "bar", "tooltip": True},
"encoding": {
"order": {"field": campo, "type": "quantitative", "sort":"descending"
},
"y": {
"field": campo,
"type": "quantitative",
"stack": "normalize",
"axis": {"format": "%", "title": campo}
},
"x": {"field": "Year", "type": "nominal"},
"color": {
"field": grupo,
"type": "nominal",
"scale": {"scheme": "category20b"}
},
"tooltip": [
{"field": campo, "type": "quantitative", "title": campo, "format": ".2s"},
{"field": grupo, "type": "nominal", "title": grupo},
],
}
}
],
"width": 600
})