Following the money: contracts and procurement
Source:vignettes/following-the-money.Rmd
following-the-money.RmdPublic procurement data is where open legislative data meets social accountability. This vignette explores the Assembly’s contracts and bidding processes.
Contract values by modality
contracts <- alepe_contracts()
contracts |>
summarise(
n = n(),
total_brl = sum(valor, na.rm = TRUE),
.by = modalidade
) |>
arrange(desc(total_brl))
#> # A tibble: 10 × 3
#> modalidade n total_brl
#> <chr> <int> <dbl>
#> 1 Pregão Eletrônico 325 397636268.
#> 2 Pregão Presencial 86 107029186.
#> 3 Concorrência - Presencial 11 96633877.
#> 4 NA 46 59623440.
#> 5 Dispensa 67 57009695.
#> 6 Inexigibilidade 70 20914208.
#> 7 Convite 38 3071596.
#> 8 Concorrência - Eletrônica 1 1865008.
#> 9 Tomada de Preços 1 777140
#> 10 Dispensa Eletrônica 1 9980Largest contractors
contracts |>
summarise(total_brl = sum(valor, na.rm = TRUE), .by = contratada) |>
slice_max(total_brl, n = 10) |>
ggplot(aes(x = reorder(contratada, total_brl), y = total_brl / 1e6)) +
geom_col(fill = "#e6550d") +
coord_flip() +
labs(
x = NULL, y = "Total contracted (BRL, millions)",
title = "Ten largest ALEPE contractors"
) +
theme_minimal()
Contracts active today
Validity dates are parsed to Date, so filtering active
contracts is a one-liner:
contracts |>
filter(vigencia_inicio <= Sys.Date(), vigencia_fim >= Sys.Date()) |>
select(contratada, objeto, valor, vigencia_fim) |>
arrange(vigencia_fim)
#> # A tibble: 53 × 4
#> contratada objeto valor vigencia_fim
#> <chr> <chr> <dbl> <date>
#> 1 FRANCIELE ELETRO LTDA 5.000… 8.12e4 2026-08-18
#> 2 V. S. COSTA & CIA LTDA 5.000… 1.7 e4 2026-08-24
#> 3 NORT MED PRODUTOS HOSPITALARES LTDA 5.000… 1.49e5 2026-08-28
#> 4 R G DISTRIBUIDORA DE ALIMENTOS LTDA 5.000… 2.59e4 2026-09-03
#> 5 54.024.431 JEFFERSON PEREIRA MELO DO NAS… 5.000… 2.44e4 2026-09-03
#> 6 MAPROS LTDA 5.000… 1.87e6 2026-09-08
#> 7 GPB SERVICOS LTDA 5.000… 5.48e5 2026-09-17
#> 8 IURY HERLEN DE SOUZA SANTOS LTDA 5.000… 5.33e6 2026-10-13
#> 9 MCR SISTEMAS E CONSULTORIA LTDA 1.204… 5.71e5 2026-10-18
#> 10 INSTITUTO SAUDE EXPRESS 5.000… 3.28e6 2026-10-23
#> # ℹ 43 more rowsProcurement outcomes
/licitacoes is the slowest endpoint of the API — allow
it half a minute, and remember that a failed request yields a zero-row
tibble rather than an error:
procurements <- alepe_procurements()
nrow(procurements)
#> [1] 618
procurements |>
count(ano, status) |>
ggplot(aes(x = ano, y = n, fill = status)) +
geom_col() +
labs(
x = NULL, y = "Processes",
fill = NULL,
title = "ALEPE procurement processes by year and status"
) +
theme_minimal() +
theme(legend.position = "bottom") +
guides(fill = guide_legend(ncol = 1))