Skip to contents

A sanity check to run right after generating data. For each baseline covariate and each endpoint (dvid), it compares the distribution in the source against the one in the synthetic dataset.

Usage

compare_pmx_distributions(
  source,
  synthetic = NULL,
  roles,
  output = c("plots", "tables")
)

Arguments

source

Source PMX data.

synthetic

Generated synthetic PMX data, or NULL to summarize source on its own.

roles

Explicit roles from pmx_roles().

output

"plots" for the figure, "tables" for the numbers behind it. The figure needs ggplot2 and patchwork.

Value

With output = "tables", a pmx_distribution_summary: a list of endpoints, covariates_numeric, and covariates_categorical data frames, each NULL when the dataset declares no columns of that kind. With output = "plots", one composed ggplot. Either carries a "release_status" attribute.

Details

By default it draws them: one panel per endpoint and per covariate, source in blue against synthetic in orange. A panel holding more than eight distinct values is drawn as overlaid density curves, each scaled to peak at 1, with a rug of the values themselves when there are few enough to see; a panel with eight or fewer is drawn as proportion bars, which is what makes an ordinal, count or binary endpoint readable. A panel whose values are all positive and span more than two orders of magnitude gets a log10 axis. output = "tables" returns the numbers instead: n, mean, standard deviation, minimum, quartiles and maximum for the dependent variable and continuous covariates, per-level counts and proportions for categorical ones.

Pass compare_pmx_distributions_height() to a chunk's fig.height. The figure grows a row of panels at a time and the chunk option is fixed before the chunk runs, so nothing else can size it.

This is the distributional companion to compare_pmx(). That function answers whether the structure matches — schema, event grammar, row and event counts; this one answers whether the numbers land in the same range. It is a diagnostic, not a validation of statistical fidelity: AVATAR and the differentially private engines deliberately do not reproduce source distributions exactly, so expect the two to be close in magnitude and shape, not identical.

Figure and tables alike are source-derived, so each is marked "restricted_not_releasable": it reads real covariate and endpoint values and stays under the source data's access controls like any other source-versus-synthetic diagnostic.

See also

compare_pmx() for the structural comparison, and compare_pmx_distributions_height() for sizing the figure.

Examples

data <- pmx_simulated_fixture(20)
roles <- pmx_roles(
  id = "ID", time = "TIME", dv = "DV", amt = "AMT", evid = "EVID",
  cmt = "CMT", dvid = "DVID", covariates = c("WT", "SEX")
)
synthetic <- suppressWarnings(synpmx_avatar(data, roles, seed = 1))
#> synpmx_avatar(): dropped 8 undeclared column(s): NTIME, TAD, OCC, RATE, MDV, CENS, LIMIT, AGE.
#>   Declare a column in `keep` to carry it through verbatim.
compare_pmx_distributions(data, synthetic, roles, output = "tables")
#> PMX source-versus-synthetic distribution summary
#> 
#> Endpoints (dependent variable on observation rows):
#>  variable   dataset   n n_subjects mean   sd   min  q25 median  q75  max
#>        cp    source 160         20 3.75 2.88  0.88 1.33   2.66 5.29 9.52
#>        cp synthetic 160         20 3.95 3.18 0.628 1.33   2.76 5.98   14
#>        pd    source 120         20   60 14.3  35.2 48.6   59.6 71.3 89.6
#>        pd synthetic 120         20 57.9 16.8  21.5 43.6   55.7 69.7  101
#> 
#> Continuous covariates (baseline, per subject):
#>  variable   dataset  n mean   sd  min  q25 median  q75 max
#>        WT    source 20 71.4 9.01   58 62.6   73.8 79.5  82
#>        WT synthetic 20 72.9 7.92 61.1 64.7   76.7 79.8  81
#> 
#> Categorical covariates (baseline, per subject):
#>  variable   dataset  level  n proportion
#>       SEX    source female 10        0.5
#>       SEX    source   male 10        0.5
#>       SEX synthetic female 13       0.65
#>       SEX synthetic   male  7       0.35
#> 
#> Source-derived; not releasable unless separately public or privately budgeted.