Sweeps `p` and, for each value, evaluates [unicity_fraction()] over subsets of `attributes` of that size. Small `p` are enumerated exhaustively whenever there are no more than `n_samples` subsets, which makes those rows exact rather than sampled; larger `p` fall back to a random sample of subsets.
Usage
unicity(
dat,
attributes,
p = seq_along(attributes),
n_samples = 100,
seed = 0L,
tolerance = reid_tie_tolerance()
)Arguments
- dat
a data frame with one row per individual (master form)
- attributes
character vector of the attribute columns an attacker might know
- p
integer vector of subset sizes to evaluate (default: every size from 1 to `length(attributes)`)
- n_samples
maximum number of attribute subsets evaluated per `p` (default 100)
- seed
integer seed for the subset sampling (default 0L, so a plain call is reproducible); NULL uses the ambient RNG stream
- tolerance
relative tolerance for calling two numeric values the same, passed to [unicity_fraction()]
Value
a data frame with one row per value of `p` and columns
- p
number of known attributes
- n_subsets
how many attribute subsets were evaluated
- exhaustive
TRUE when every subset of that size was evaluated, so `unicity_mean` is exact rather than estimated
- unicity_mean, unicity_sd, unicity_min, unicity_max
fraction of records that are unique, averaged over those subsets, with its spread
Details
The result is a plain data frame so it can go straight into a report.
`attributes` must not include a record identifier: a column that is unique by construction (a row number, a customer ID) would drive the curve to 1 and say nothing about the data.
Examples
d <- create_dummy_qi_data(people = 50, seed = 1)
unicity(d, attributes = c("AGE", "ZIP", "SEX", "VISIT_COUNT", "SPEND_MEAN"))
#> p n_subsets exhaustive unicity_mean unicity_sd unicity_min unicity_max
#> 1 1 5 TRUE 0.272 0.33929338 0.00 0.78
#> 2 2 10 TRUE 0.760 0.32180049 0.06 1.00
#> 3 3 10 TRUE 0.974 0.05966574 0.82 1.00
#> 4 4 5 TRUE 1.000 0.00000000 1.00 1.00
#> 5 5 1 TRUE 1.000 0.00000000 1.00 1.00