Skip to contents

The 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