Following the money: contracts and procurement

Public procurement data is where open legislative data meets social accountability. This vignette explores the Assembly’s contracts and bidding processes.

library(alepe)
library(dplyr)
library(ggplot2)

Contract values by modality

contracts <- alepe_contracts()

contracts |>
  summarise(
    n = n(),
    total_brl = sum(valor, na.rm = TRUE),
    .by = modalidade
  ) |>
  arrange(desc(total_brl))

Largest 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()

The ALEPE API did not return contracts while this page was being built, so the chart is omitted. Run the code above yourself for current data.

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)

Procurement 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)
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))

The ALEPE API did not return procurement processes while this page was being built, so the chart is omitted. Run the code above yourself for current data.