Takes one data frame and a user-edited roles table (from
propose_roles(), possibly adjusted with set_role()) and produces
a synthetic clone according to each column's action. Returns a
masque S7 object holding the synthetic data and a private
masque_recipe.
Arguments
- df
A data frame.
- roles
A roles table from
propose_roles()(possibly edited). Tables from masque <= 0.5.0 are upgraded with a deprecation warning; seeroles_validate().- mode
Either
"local"or"collaborate". When omitted, inheritattr(roles, "mode"), falling back to"local"for a roles table with no mode provenance. An explicit collaborate-to-local downgrade raises a classedmasque_mode_downgradewarning.- seed
Optional integer for reproducibility.
- clean
Label and column-name hygiene before masking, passed to
clean_table(): one of"auto"(default - trim whitespace and report near-duplicate labels),"report"(report only), or"off"(skip). Invalid column names are legalised in every mode – an invalid name silently rewritten during synthesis corrupts the clone – and the repair is raised as amasque_name_repairedwarning. Therolestable's column references are remapped to the legalised names, the fixes are recorded in the recipe, andapply_recipe()/unmask()reverse them on the round-trip.- alias_names
Hide the column names themselves.
FALSE(the default) keeps them.TRUEreplaces every retained column name with an opaque alias (col_001,col_002, ... in column order). A character vector names just the columns to alias. The original-to-alias map is stored in the recipe and inverted byapply_recipe()/unmask(), so a pipeline written against the aliased synthetic round-trips. Column names are the last identifying surface a kept or design column exposes; alias them when even the schema is sensitive.- conditional
Logical scalar (default
FALSE). The collaborate-grade conditional clone. WhenFALSE, scrambled numeric columns are re-simulated from one global Gaussian copula - marginals and global covariance survive, but the treatment-to-outcome relationship does not, so a causal model fitted on the clone recovers a null effect. WhenTRUE, the numeric block is re-simulated within each treatment-by-design stratum, so a row's synthetic outcome inherits the location of the treatment that row carries. A causal model fitted on the conditional clone recovers the real treatment effect within sampling tolerance - the data-side analogue of preserving a conditional mean embedding rather than a pooled marginal. The conditioning columns (treatment plus retained design) are recorded on the recipe. With no treatment or design column to condition on, the path degrades cleanly to the global copula and a note is emitted.- coords
Optional geographic-coordinate declaration. Supply one or more latitude/longitude pairs and each is coarsened in place by an on-land jitter (see
jitter_coordinates()) instead of being copula-scrambled into implausible locations. A pair is a named vectorc(lat = "lat_col", lon = "lon_col")or a named list that also carries jitter parameters (method,min_km,max_km,sd_km,on_land); pass several pairs as a list. Defaults to a donut of 5-20 km on land. A declared pair always survives masking, coarsened; the recipe records that it was coarsened andapply_recipe()retargets to the real coordinates.Internal. A named list of pre-computed
original -> aliaslevel maps for cross-table linked columns, set bymask_set(). Not for direct use.- ...
Must be empty. An unused argument (for example a misspelled name) errors rather than being silently ignored.
Value
A masque S7 object. Use synthetic() and recipe() to
extract the components.
Details
mode = "local" marks the synthetic for owner development only; the
reminder is recorded on the recipe and shown when the object prints.
mode = "collaborate" additionally jitters re-simulated numerics
within their measurement resolution (stochastically rounding
integers) and runs audit_mask() automatically; a HIGH finding is
raised as a classed warning (masque_high_leakage) and blocks the
package-managed writers (masque()'s out, write_set()) until it
is resolved or explicitly overridden. Which columns are aliased,
kept, or dropped is decided by the action column of roles -
propose_roles() resolves mode-appropriate defaults, so the table
you reviewed is the plan that runs.
Collaborate mode adjusts the transformations and runs the audit; it does not model where the output will go. Whether a synthetic table is appropriate for a given collaborator, environment, or jurisdiction is a release decision that stays with the data custodian - masque informs that decision, it does not make it.
Behaviour by action
keepByte-identical pass-through, both modes.
scrambleNumeric outcome / covariate columns are re-simulated jointly via a Gaussian copula on the global Pearson covariance, with empirical-quantile marginals. Categorical, date, and text columns are row-permuted within non-NA positions, class preserved. Treatment columns get a seeded label permutation - the assignment structure never moves.
aliasAs
scramblewhere applicable, plus opaque label substitution: treatments becometrt_NNN(<col>_trt_NNNwhen two or more treatment factors are aliased), categorical covariates<col>_LNNN, design labels<col>_DNNN(in place - structure intact), ids<col>_INNN(in place - row linkage intact), text values<col>_TNNN.dropColumn excluded from the synthetic, both modes.
The NA mask of every retained column is preserved cell-by-cell. RNG state is preserved across the call.
Examples
r <- propose_roles(iris)
r <- set_role(r, "Sepal.Length", role = "outcome")
m <- mask(iris, r, seed = 1)
head(synthetic(m))
#> # A tibble: 6 × 5
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> <dbl> <dbl> <dbl> <dbl> <fct>
#> 1 5.1 3.2 4 1.5 setosa
#> 2 6 3 3.7 0.4 setosa
#> 3 5 3 4.6 1.1 setosa
#> 4 7.2 2.6 5.8 1.7 setosa
#> 5 6.1 2.4 5.8 1.5 setosa
#> 6 5 2.7 4.5 1.4 setosa