Structurally faithful development surrogates for tabular data.
masque makes a synthetic copy of a confidential table that keeps its
design, missing values and correlations. Analysts write and test code on
the copy. The data custodian then runs the finished code on the real data,
using a private recipe that translates names and labels.
It is for custodians of confidential research data who want an outside analyst to build the analysis without seeing the data, and for the analysts who build it. The input can be a single table, a folder of files or a multi-sheet workbook.
Security note. Clones made with masque 0.13.0 or earlier can reveal which alias stands for which label. If you shared one, make it again with 0.14.0 and share the new clone instead. The same seed gives the same values.
The changelog lists what changed in each release.
Every table masque returns is a data.table.
Pre-built binaries from r-universe:
install.packages(
"masque",
repos = c("https://max578.r-universe.dev", "https://cloud.r-project.org")
)
Or from GitHub:
# install.packages("pak")
pak::pak("max578/masque")
library(masque)
# Read a small public fixture (alpha-design field trial; John & Williams, 1995).
f <- system.file("extdata", "john_alpha.csv", package = "masque")
df <- read.csv(f, stringsAsFactors = TRUE)
# One guided call: read -> propose roles -> (review) -> mask -> audit.
# In an interactive session it pauses to let you review the plan;
# ask = FALSE skips the pause.
m <- masque(df, mode = "collaborate", seed = 1L)
synth <- synthetic(m) # hand this to the analyst
rec <- recipe(m) # keep this private
# Analyst builds a pipeline against the synthetic namespace ...
fit <- lm(yield ~ gen + rep, data = synth)
# ... and the custodian re-targets it to the original data.
preds <- predict(fit, newdata = apply_recipe(df, rec))
A folder of files or a multi-sheet workbook works the same way. Pass the
path to masque() and it masks every table at once, aliasing shared keys
consistently so the synthetic tables still join.
If the table needs tidying first, clean_table() makes column names valid
and trims whitespace, and conform_table() merges near-duplicate labels
and sets column types, reporting each change.
detect_design() recognises environment columns, such as site or year, and
the design within each environment. In collaborate mode the environment
labels are aliased and every row stays in its environment. The clone does
not keep genotype-by-environment effects, so it is no substitute for the
real data in scientific inference.
masque is not a privacy-preserving or differential-privacy tool. It is a
structurally faithful development surrogate with explicit confidentiality
guardrails. Read
Confidentiality and the threat model
before using it.
What masque does
local for owner-only realistic surrogates,
and collaborate for controlled sharing with opaque aliasing, numeric
jitter, and an automatic leakage audit.conditional = TRUE). Treatment means on the clone then track those of
the real data, and block and environment effects stay detectable.
What a conditional clone keeps of the design
tests this on eight field designs.recipe. The recipe holds the real labels, the original column names and
the seed, so together with the synthetic it undoes every alias. Keep it
with the original data and never send it with the synthetic.audit_mask()), raises HIGH findings as classed
warnings the guided flow never silences, and refuses package-managed writes
while a HIGH finding stands (an explicit allow_high = TRUE override is
available, warned and recorded in the recipe).What masque does not do
Bottom line. Generating a synthetic table is not a release decision.
In the Five Safes framework for controlled data access, masque
contributes to Safe Data and Safe Outputs;
Safe People, Safe Projects, and Safe Settings are governance questions no
package can answer. The collaborate workflow assumes only the synthetic
crosses the trust boundary.
Both produce data meant to be analysed in place of the original. masque
produces a development copy: analysts write code on it and the custodian
runs that code on the real data through the private recipe. It keeps the
experimental design (treatments, blocks, plots), and a conditional clone
(conditional = TRUE) also keeps the treatment means of the outcome.
Every column's role and action is checked against a fixed vocabulary
before anything is masked.
Articles, in reading order:
The function reference documents every exported function. Also on the site: API stability policy, changelog, contributing guide and licence.
Bug reports and suggestions are welcome as GitHub issues. Read the contributing guide before opening a pull request.
citation("masque")
The package also ships a CITATION.cff file.
MIT. See the licence.