Official Statistics Workflow with DPrivStats

library(DPrivStats)
set.seed(11)

This vignette sketches an official-statistics workflow: combining multiple DP tabulations under a single budget, applying post-processing constraints, and comparing composition rules.

Combining releases under one budget

budget <- new_privacy_budget(epsilon = 4.0, delta = 1e-6, composition = "rdp")

if (can_spend(budget, 1.5)) {
  budget <- spend(budget, 1.5, "mean income by region table")
}

if (can_spend(budget, 1.5)) {
  budget <- spend(budget, 1.5, "education histogram")
}
budget
#> 
#> Privacy Budget (composition: rdp )
#>   total epsilon:  4.000
#>   spent epsilon:  0.000
#>   accumulated rho: 0.0000
#>   remaining:      4.000

Post-processing constraints

DP histograms can contain negative noisy counts; truncating at zero and normalizing are pure post-processing steps that preserve DP:

data(example_microdata)
h <- dp_histogram(example_microdata$age, epsilon = 1.0,
                  breaks = seq(10, 90, by = 10), normalize = TRUE)
h$estimate # already non-negative by construction
#>    [10,20]    (20,30]    (30,40]    (40,50]    (50,60]    (60,70]    (70,80] 
#> 0.03190307 0.12534167 0.28326799 0.33126897 0.16600733 0.05101880 0.01119218 
#>    (80,90] 
#> 0.00000000

Composition comparison

For a fixed workflow of small releases, RDP is typically much tighter than basic composition:

eps_seq <- c(1.5, 1.5, 1.0)
compare_composition(eps_seq, delta = 1e-6)
#>   composition  epsilon
#> 1       basic  4.00000
#> 2    advanced 29.32444
#> 3         rdp 11.46696

Disclosure risk intuition

The privacy loss random variable of a Laplace release is exponential; its tail probabilities quantify the chance of large losses:

laplace_plr_tail(c(0, 3, 6), epsilon = 1.0)
#> [1] 1.000000000 0.049787068 0.002478752

mirror server hosted at Truenetwork, Russian Federation.