---
title: "Non-reports and imputation"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Non-reports and imputation}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
```

## The problem

ESTBAN is assembled by the Central Bank from the monthly returns of each
institution. Once in a while a bank's return does not make it into the
file. The bank is still listed, with every branch and every account equal
to **zero**. A documented case is Banco Santander from January to March
2025: three consecutive months at zero in the whole country, then back to
normal in April.

This is a **non-report**, not a zero balance sheet. Summing those rows into
a municipal series makes credit and deposits fall by the bank's share for
three months and jump back, and any model fed with the series reads that as
a real shock. Re-downloading does not help: the published files are what
they are.

## Detecting it

`estban_flag_nonreport()` marks every row of an institution-month whose
accounts sum to zero **across the whole table**. The wider the table, the
safer the test: one dormant branch can legitimately have zero everywhere,
but a bank with zeros in every city of a state (or of the country) has not
reported.

Let us build a three-month series from the extract shipped with the
package and make one bank vanish in February:

```{r}
library(estbanr)

f  <- system.file("extdata", "202401_ESTBAN_AG_sample.CSV", package = "estbanr")
m1 <- estban_read(f, uf = "PE")
verb <- grep("^verbete_", names(m1))

m2 <- m1; m2$ref <- 202402L; m2[, verb] <- m2[, verb] * 1.05
m3 <- m1; m3$ref <- 202403L; m3[, verb] <- m3[, verb] * 1.10
m2[m2$cnpj == "60746948", verb] <- 0          # Bradesco: nothing in February

x <- rbind(m1, m2, m3)
flagged <- estban_flag_nonreport(x)
unique(flagged[flagged$nonreport, c("nome_instituicao", "ref")])
```

## Fixing it

`estban_impute_nonreport()` treats the flagged institution-months as
missing, collapses branches to one row per institution and municipality,
and fills **interior** gaps by linear interpolation along each
(institution, municipality, account) series. Gaps at the start or end of a
series are left as `NA`: a bank that stopped reporting last month stays
missing until the file is revised, instead of being invented.

```{r}
imp <- estban_impute_nonreport(x)
v <- "verbete_160_operacoes_de_credito"
imp[imp$cnpj == "60746948" & imp$municipio == "CARUARU", c("ref", v, "imputed")]
```

February is now the midpoint of January and March, and the `imputed`
column says how many accounts were filled in that row (all 45).

## Effect on the municipal series

`estban_by_municipality()` runs the imputation by default. Compare the
credit series of Caruaru with and without it:

```{r}
raw <- estban_by_municipality(x, impute = FALSE)
fix <- estban_by_municipality(x)
data.frame(
  ref     = raw$ref[raw$municipio == "CARUARU"],
  raw     = raw[[v]][raw$municipio == "CARUARU"],
  imputed = fix[[v]][fix$municipio == "CARUARU"]
)
```

Without the treatment, February is short by the whole credit of the missing
bank (here a small share of the city, so the total does not even fall, which
is exactly what makes the error hard to spot); with it, February sits between
January and March as it should.

## When not to impute

* **Short extracts.** With a single month there are no neighbours; the
  flag still works, the interpolation cannot.
* **Genuine exits.** A bank that closed all branches in a municipality
  shows zero from then on. That is an edge gap and is left as `NA` by
  design, but if the closure happened *between* two reported months in
  your window (it reopened later), the interpolation would bridge it. Look
  at the `imputed` column and at `nonreport` before trusting a long
  bridge.
* **Balance identities.** Interpolated accounts no longer add up exactly to
  the totals (`verbete_399_total_do_ativo`, `verbete_899_total_do_passivo`),
  because each account is interpolated separately. Recompute totals from
  components if you need the identity.
