Official Statistics Workflow with PUMS-like Microdata

Official Statistics Workflow with PUMS-like Microdata

Statistical agencies need consistent marginals and releasable privacy reports when publishing synthetic microdata.

library(DPSynth)
data(acs_pums_sample)
set.seed(2)

synth <- dp_synthesize(acs_pums_sample, method = "copula",
                       epsilon = 3.0, delta = 1e-6, n_synth = 500,
                       risk_audit = FALSE)
#> Warning in regularize.values(x, y, ties, missing(ties), na.rm = na.rm):
#> collapsing to unique 'x' values
#> Warning in regularize.values(x, y, ties, missing(ties), na.rm = na.rm):
#> collapsing to unique 'x' values
print(synth)
#> === Differentially Private Synthetic Data ===
#> Method: copula 
#> Privacy: (epsilon = 3 , delta = 1e-06 )
#> Synthetic records: 500 
#> 
#> --- Utility Summary ---
#> Propensity pMSE ratio: 0.0017 
#> Correlation distance: 0.0669

# Post-processing: enforce non-negative income
synth$synthetic_data$income <- pmax(synth$synthetic_data$income, 0)

Consistency of released marginals:

u <- evaluate_univariate(synth$synthetic_data, acs_pums_sample)
u
#>       variable ks_stat   hellinger mean_rel_err sd_rel_err
#> 1          age   0.088 0.052894668  0.017895487 0.02693081
#> 2       income   0.060 0.001288482  0.009984623 0.03192774
#> 3         educ      NA 0.026697585           NA         NA
#> 4      married      NA 0.001699055           NA         NA
#> 5 weeks_worked   0.050 0.083015751  0.000738651 0.02209530

Releasing the privacy report alongside the synthetic file:

budget <- new_synth_budget(epsilon = 5, delta = 1e-6, accounting = "rdp")
budget <- spend_synth(budget, 3.0, description = "DP-copula synthesis")
#> Warning in spend_synth(budget, 3, description = "DP-copula synthesis"): Privacy
#> budget exceeded! Synthesis may not satisfy DP.
budget <- spend_synth(budget, 1.0, description = "DP marginal check")
#> Warning in spend_synth(budget, 1, description = "DP marginal check"): Privacy
#> budget exceeded! Synthesis may not satisfy DP.
check_synth_budget(budget)
#> remaining_epsilon     spent_epsilon     fraction_used 
#>          0.000000         23.815511          4.763102