how far containment narrows the candidate set, per ANON record
Source:R/generalize.R
containment_counts.RdThe direct read-out of Issue #20's verification question: given the generalised release, how many RAW records could each published record have come from?
Usage
containment_counts(
dat_raw_anon,
targets,
row_number = "ROW_NUMBER",
hierarchy = NULL,
rules = NULL,
units = generalization_units()
)Arguments
- dat_raw_anon
dataframe of raw_anon form
- targets
character vector of column names (before RAW_/ANON_ prefixing) to intersect
- row_number
name of the row-number column *before* the RAW_/ANON_ prefixing done by [join_raw_anon_data()] (default: "ROW_NUMBER")
- hierarchy
a "reid_hierarchy" object from [read_generalization_hierarchy()] or [generalization_hierarchy()], or NULL (the default) when every generalisation is an interval that speaks for itself
- rules
optional named character vector forcing a rule per column, one of `"auto"` (default: interval if the value parses as one, else exact string equality, in both cases widened by the hierarchy), `"interval"`, `"exact"` or `"prefix"` (for masked codes such as `"135****"`)
- units
unit strings that may follow a number, see [generalization_units()]
Warns when any ANON record ends up with an **empty** candidate set. That is the failure Issue #101 is about: nothing is contained, every candidate ties at 1, and the record contributes the random baseline to the reported rate – while [reid_evaluate()]'s `blocked` / `n_true_missing` / `truth_coverage` all still report a healthy join, because the candidate table keeps its full shape. The warning names the published values that excluded everybody.
Value
a data frame with one row per ANON record and columns
- ANON_ROW_NUMBER
the record
- N_CANDIDATES
RAW records offered to it
- N_CONTAINED
how many survive containment (the `k` above)
- NARROWED_TO
`N_CONTAINED / N_CANDIDATES`
- INFORMATION
`1 / N_CONTAINED`, the attacker's chance, `NA` when nothing survives
- TRUTH_CONTAINED
whether the record's own RAW counterpart survived
Details
`TRUTH_CONTAINED` is a correctness check on the *set-up*, not a risk measure. If the record's real counterpart is not inside its own published region, the generalisation and the raw data disagree – a wrongly declared hierarchy, a unit mismatch, a column that was rounded rather than binned – and every risk number computed from it is meaningless. It should be `TRUE` for every record of a correctly generalised release, and it is reported rather than assumed because a silent `FALSE` looks exactly like safety.
Examples
raw <- data.frame(ROW_NUMBER = 1:6, AGE = c(21, 24, 33, 37, 38, 52))
anon <- data.frame(ROW_NUMBER = 1:6, AGE = c("20s", "20s", "30s", "30s",
"30s", "50s"))
containment_counts(join_raw_anon_data(raw, anon), "AGE")
#> ANON_ROW_NUMBER N_CANDIDATES N_CONTAINED NARROWED_TO INFORMATION
#> 1 1 6 2 0.3333333 0.5000000
#> 2 2 6 2 0.3333333 0.5000000
#> 3 3 6 3 0.5000000 0.3333333
#> 4 4 6 3 0.5000000 0.3333333
#> 5 5 6 3 0.5000000 0.3333333
#> 6 6 6 1 0.1666667 1.0000000
#> TRUTH_CONTAINED
#> 1 TRUE
#> 2 TRUE
#> 3 TRUE
#> 4 TRUE
#> 5 TRUE
#> 6 TRUE