panel_balance() trims a panel to a balanced
rectangle – a block of years in which every retained
organization is observed in every retained year. It is the complement of
panel_complete(): completion fills gaps to reach a
full rectangle, balancing drops organizations and years to
reach one.
df <- data.frame(
EIN2 = c(rep("A", 4), rep("B", 4), rep("C", 3), rep("D", 2)),
TAX_YEAR = c(2019:2022, 2019:2022, 2019:2021, c(2019, 2020))
)A and B are observed all four years;
C misses 2022; D only appears in
2019–2020.
The year window is the trade-off
A wider window keeps more years but fewer
organizations; a narrower one keeps more organizations.
By default panel_balance() uses the full observed range –
the strictest balance:
full <- panel_balance(df)
unique(full$EIN2) # only orgs present in all of 2019-2022
#> [1] "A" "B"
attr(full, "balance")
#> $years
#> [1] 2019 2020 2021 2022
#>
#> $n_years
#> [1] 4
#>
#> $orgs_kept
#> [1] 2
#>
#> $orgs_dropped
#> [1] 2Restrict the window and more organizations qualify:
win <- panel_balance(df, years = 2019:2021)
unique(win$EIN2) # C now qualifies; D still does not
#> [1] "A" "B" "C"Let it find the largest block
If you would rather have the package pick the window that retains the
most data (organizations x years), use
strategy = "max_rectangle":
best <- panel_balance(df, strategy = "max_rectangle")
attr(best, "balance")[c("years", "orgs_kept")]
#> $years
#> [1] 2019 2020 2021
#>
#> $orgs_kept
#> [1] 3Here the 3-year x 3-organization block (2019–2021, A/B/C = 9
observations) beats the full 4-year x 2-organization block (8), so that
is what it returns. min_years sets a floor on how short a
balanced window may be.
Notes
The "balance" attribute always records the retained
years and the keep/drop counts. If no organization spans the window, the
result is simply empty (zero rows) rather than an error – a useful
signal that your window is too demanding. And because balancing only
selects rows, run deduplicate() first if an
organization can have more than one filing per year, so each cell of the
rectangle is a single record.