| Title: | Brazilian Monthly Banking Statistics by Municipality (ESTBAN) |
| Version: | 0.1.1 |
| Description: | Download, read and tidy the ESTBAN (Estatistica Bancaria Mensal por Municipio, Monthly Banking Statistics by Municipality) files published by the Brazilian Central Bank (Banco Central do Brasil) for every bank branch and municipality in Brazil. Each file reports balance-sheet accounts of the COSIF (Plano Contabil das Instituicoes do Sistema Financeiro Nacional, the chart of accounts of the Brazilian financial system) such as credit operations, deposits and savings. Files are fetched from the official site https://www.bcb.gov.br/estatisticas/estatisticabancariamunicipios with an idempotent local cache, read from their Latin-1 encoded CSV (comma-separated values) layout into tibbles, optionally filtered by state, and aggregated by municipality. Includes tools to detect and impute institution-month non-reports (an institution present in the file with every account equal to zero), which would otherwise be mistaken for zero balances. |
| License: | MIT + file LICENSE |
| URL: | https://strategicprojects.github.io/estbanr/, https://github.com/StrategicProjects/estbanr |
| BugReports: | https://github.com/StrategicProjects/estbanr/issues |
| Encoding: | UTF-8 |
| Language: | en-US |
| Depends: | R (≥ 4.1.0) |
| Imports: | cli (≥ 3.6.0), dplyr (≥ 1.1.0), httr2 (≥ 1.0.0), readr (≥ 2.1.0), rlang (≥ 1.1.0), stats, stringi (≥ 1.7.0), tibble (≥ 3.2.0), utils |
| Suggests: | knitr, rmarkdown, testthat (≥ 3.0.0), withr |
| Config/testthat/edition: | 3 |
| VignetteBuilder: | knitr |
| Config/roxygen2/version: | 8.0.0 |
| NeedsCompilation: | no |
| Packaged: | 2026-09-22 11:51:01 UTC; leite |
| Author: | Andre Leite |
| Maintainer: | Andre Leite <leite@castlab.org> |
| Repository: | CRAN |
| Date/Publication: | 2026-09-30 12:40:02 UTC |
estbanr: Brazilian Monthly Banking Statistics by Municipality (ESTBAN)
Description
Download, read and tidy the ESTBAN (Estatistica Bancaria Mensal por Municipio, Monthly Banking Statistics by Municipality) files published by the Brazilian Central Bank (Banco Central do Brasil) for every bank branch and municipality in Brazil. Each file reports balance-sheet accounts of the COSIF (Plano Contabil das Instituicoes do Sistema Financeiro Nacional, the chart of accounts of the Brazilian financial system) such as credit operations, deposits and savings. Files are fetched from the official site https://www.bcb.gov.br/estatisticas/estatisticabancariamunicipios with an idempotent local cache, read from their Latin-1 encoded CSV (comma-separated values) layout into tibbles, optionally filtered by state, and aggregated by municipality. Includes tools to detect and impute institution-month non-reports (an institution present in the file with every account equal to zero), which would otherwise be mistaken for zero balances.
Author(s)
Maintainer: Andre Leite leite@castlab.org (ORCID)
Authors:
Andre Leite leite@castlab.org (ORCID)
Marcos Wasiliew marcos.wasiliew@sepe.pe.gov.br
Hugo Vasconcelos hugo.vasconcelos@ufpe.br (ORCID)
Carlos Amorim carlos.agaf@ufpe.br (ORCID)
Diogo Bezerra diogo.bezerra@ufpe.br (ORCID)
Júlia Nascimento Barreto juliabarreto@gd.seplag.pe.gov.br
See Also
Useful links:
Report bugs at https://github.com/StrategicProjects/estbanr/issues
Aggregate ESTBAN to the municipality
Description
Sums every account over the institutions (and branches) of each
municipality and month. With impute = TRUE (the default) non-reported
institution-months are interpolated first with
estban_impute_nonreport(), so the municipal series does not collapse
when a bank is missing from a file.
Usage
estban_by_municipality(df, impute = TRUE, long = FALSE)
Arguments
df |
A tibble from |
impute |
Logical. Interpolate non-reports before summing (default
|
long |
Logical. Return one row per municipality, month and account
( |
Value
A tibble keyed by uf, codmun_ibge, municipio and ref.
In wide form the account columns follow; in long form the columns
verbete (clean column name) and value follow.
Examples
f <- system.file("extdata", "202401_ESTBAN_AG_sample.CSV", package = "estbanr")
x <- estban_read(f)
m <- estban_by_municipality(x, impute = FALSE)
m[, c("uf", "municipio", "ref", "verbete_160_operacoes_de_credito",
"verbete_420_depositos_de_poupanca")]
head(estban_by_municipality(x, impute = FALSE, long = TRUE))
Resolve the estbanr cache directory
Description
The directory where downloaded ESTBAN files are kept. Resolution order:
Usage
estban_cache_dir(cache_dir = NULL, create = TRUE)
Arguments
cache_dir |
Optional directory path. When |
create |
Logical. Create the directory when it does not exist
(default |
Details
the
cache_dirargument;the
ESTBANR_CACHE_DIRenvironment variable;the
estbanr.cache_dirR option;a session-scoped folder under
base::tempdir()(the default, so the package never writes outside the temporary directory unless you opt in).
Set one of the persistent options (2 or 3) to keep files across sessions and avoid re-downloading months you already have.
Value
A normalized directory path (character scalar).
Examples
estban_cache_dir()
# Persistent cache for the current session only:
old <- options(estbanr.cache_dir = file.path(tempdir(), "estban-cache"))
estban_cache_dir()
options(old)
Normalize ESTBAN column names to snake_case
Description
Lower case, accents stripped, every run of non-alphanumeric characters
collapsed to a single underscore. Combined columns such as
"VERBETE_141_... + VERBETE_142_..." become one long name, so nothing is
lost and estban_verbetes() can map the name back to its account codes.
Usage
estban_clean_names(x)
Arguments
x |
Character vector of column names. |
Value
Character vector.
Examples
estban_clean_names(c("#DATA_BASE", "VERBETE_160_OPERACOES_DE_CREDITO",
"VERBETE_174_PROV_P/_OPER_CREDITOS"))
ESTBAN column layout and account dictionary
Description
estban_columns() lists the columns of the monthly file for a level, in
file order, with their snake_case names. estban_verbetes() restricts
the list to the balance-sheet accounts (VERBETE_*), parsing the
three-digit 'COSIF' codes out of the column name. Some columns combine
several accounts (for instance VERBETE_141 + VERBETE_142); those have
more than one code in codes and n_codes > 1.
Usage
estban_columns(level = c("agencia", "municipio"))
estban_verbetes(level = c("agencia", "municipio"))
Arguments
level |
|
Details
The dictionary is built from the January 2024 files (see
data-raw/verbetes.R in the source repository) and covers both levels,
which share the same accounts.
Value
A tibble. estban_columns() has position, column (original
name), name (clean name) and kind ("id" or "verbete").
estban_verbetes() has column, name, codes (character, codes
separated by ;), code (first code, integer), n_codes, side
("ativo" for codes below 400, "passivo" otherwise) and
description.
Examples
estban_columns()[1:8, ]
v <- estban_verbetes()
v[v$code %in% c(160, 420, 432), c("name", "codes", "side")]
# Combined columns
v[v$n_codes > 1, c("codes", "n_codes")]
Download one ESTBAN month
Description
Downloads the monthly file for ref, trying each name variant from
estban_url(), unzips it when needed and returns the path to the CSV in
the cache directory. Months already in the cache are not downloaded
again unless force = TRUE.
Usage
estban_download(
ref,
level = c("agencia", "municipio"),
cache_dir = NULL,
force = FALSE,
timeout = 300,
verbose = TRUE
)
Arguments
ref |
Reference month as |
level |
|
cache_dir |
Directory for downloaded files. See |
force |
Logical. Re-download even when the CSV is already cached. |
timeout |
Seconds allowed for one download (default 300). |
verbose |
Logical. Emit progress messages (default |
Value
The path to the cached CSV (invisibly NULL when the month is
not published under any of the known names, with a warning).
Examples
# Needs network access to www.bcb.gov.br (about 2 MB); skipped when offline.
csv <- tryCatch(estban_download(202401, verbose = FALSE),
error = function(e) NULL)
if (!is.null(csv)) {
pe <- estban_read(csv, uf = "PE")
nrow(pe)
}
Download and read a range of months
Description
Convenience wrapper around estban_download() and estban_read() for a
range of reference months. Months that are not published are skipped
with a warning, so the result may cover fewer months than requested;
check unique(result$ref).
Usage
estban_fetch(
start,
end = start,
uf = NULL,
level = c("agencia", "municipio"),
cache_dir = NULL,
clean_names = TRUE,
force = FALSE,
verbose = TRUE
)
Arguments
start, end |
Reference months as |
uf |
Optional character vector of two-letter state codes to keep
(e.g. |
level |
|
cache_dir |
Directory for downloaded files. See |
clean_names |
Logical. Convert column names to |
force |
Logical. Re-download even when the CSV is already cached. |
verbose |
Logical. Emit progress messages (default |
Value
A tibble with all requested months stacked (see estban_read()).
Examples
# Needs network access; about 2 MB per month.
x <- tryCatch(estban_fetch(202401, 202403, uf = "PE", verbose = FALSE),
error = function(e) NULL)
if (!is.null(x)) table(x$ref)
Flag institution-months that were not reported
Description
An institution can be present in an ESTBAN file with every account equal to zero in every branch and municipality of the extract. That is not a zero balance sheet: it is a non-report (the bank's return did not make it into that month's file). A documented case is Banco Santander in January to March 2025, zeroed in the whole country. Summing such rows into a municipal total makes credit and deposits collapse for three months and then jump back, which any time-series model reads as a real shock.
Usage
estban_flag_nonreport(df)
Arguments
df |
A tibble from |
Details
estban_flag_nonreport() adds a logical column nonreport that is
TRUE for every row of an institution-month whose accounts sum to zero
across the whole table. Run it on the largest extract you have (ideally a
state or the country), because the test is "zero everywhere in the
data", and a single municipality can legitimately have a dormant branch.
Value
df with an extra logical column nonreport.
Examples
f <- system.file("extdata", "202401_ESTBAN_AG_sample.CSV", package = "estbanr")
x <- estban_read(f)
x <- estban_flag_nonreport(x)
table(x$nonreport)
# A synthetic non-report: zero every account of one bank in one month
y <- x
bank <- y$cnpj == y$cnpj[[1]]
y[bank, grep("^verbete_", names(y))] <- 0
table(estban_flag_nonreport(y)$nonreport, y$cnpj == y$cnpj[[1]])
Impute non-reported institution-months
Description
Treats every institution-month flagged by estban_flag_nonreport() as
missing and fills interior gaps by linear interpolation along the
monthly series of each (institution, municipality, account). Gaps at
the start or end of a series are left as NA (no extrapolation), so a
bank that stopped reporting last month stays missing until the file is
revised, instead of being invented.
Usage
estban_impute_nonreport(df)
Arguments
df |
A tibble from |
Details
Rows are first summed to one row per institution and municipality (branches of the same bank in the same city are added), because that is the level at which the interpolation is meaningful and stable.
Value
A tibble with one row per cnpj, codmun_ibge and ref, the
identification columns, the account columns (imputed where possible)
and an integer column imputed with the number of accounts filled in
that row. A message reports how many institution-months were treated.
Examples
# Three months of a two-bank, one-city extract, with bank B zeroed in the
# middle month. See vignette("nonreport-imputation") for the full story.
f <- system.file("extdata", "202401_ESTBAN_AG_sample.CSV", package = "estbanr")
m1 <- estban_read(f, uf = "PE")
m2 <- m1; m2$ref <- 202402L
m3 <- m1; m3$ref <- 202403L
verb <- grep("^verbete_", names(m1))
m2[m2$cnpj == "60746948", verb] <- 0 # Bradesco "vanishes" in February
m3[, verb] <- m3[, verb] * 1.10 # and everything grows 10% by March
x <- rbind(m1, m2, m3)
imp <- estban_impute_nonreport(x)
imp[imp$cnpj == "60746948" & imp$municipio == "CARUARU",
c("ref", "verbete_160_operacoes_de_credito", "imputed")]
Read an ESTBAN CSV file
Description
Reads a monthly ESTBAN file as published by the Central Bank: two title
lines to skip, ; as separator, Latin-1 encoding, one row per bank
branch (level = "agencia") or per institution and municipality
(level = "municipio"). Account columns (VERBETE_*) are returned as
doubles in Brazilian reais; codes are kept as character to preserve
leading zeros.
Usage
estban_read(path, uf = NULL, clean_names = TRUE, ref = NULL)
Arguments
path |
Path to a CSV downloaded with |
uf |
Optional character vector of two-letter state codes to keep
(e.g. |
clean_names |
Logical. Convert column names to |
ref |
Optional reference month to record in the |
Value
A tibble with a leading integer column ref (AAAAMM), the
identification columns and one numeric column per account.
Examples
# A small real extract shipped with the package (PE and PB, January 2024)
f <- system.file("extdata", "202401_ESTBAN_AG_sample.CSV", package = "estbanr")
x <- estban_read(f)
x[, 1:8]
# Keep one state and the original column names
pe <- estban_read(f, uf = "PE", clean_names = FALSE)
names(pe)[1:10]
Candidate download URLs for one ESTBAN month
Description
The Central Bank has changed the file naming over the years, so for a
given month more than one name may exist. The candidates are tried in
order by estban_download(); the first that answers 200 wins.
Usage
estban_url(ref, level = c("agencia", "municipio"))
Arguments
ref |
Reference month as |
level |
|
Value
A character vector of URLs, most likely first.
Examples
estban_url(202401)
estban_url("202401", level = "municipio")