This walkthrough uses the bounded synthetic association recipe. It requires independent observations, a continuous outcome and exposure, and explicit units. It estimates an association, not a treatment effect. Paired, clustered, longitudinal and survival designs require other recipes and are not admitted by this contract. Unique observation IDs prevent accidental duplication; they do not establish that observations are independent.
The example generates new synthetic values with English column names and an explicit seed. The response-generating equation is known because this is a development example. The fitted estimates still vary with the generated noise.
data <- withr::with_seed(20261016, {
exposure <- rep(seq_len(10), 4)
age <- stats::runif(40, min = 25, max = 65)
data.frame(
observation_id = sprintf("example_%03d", seq_len(40)),
pressure = 110 + 2 * exposure + 0.15 * age + stats::rnorm(40, sd = 5),
exposure = exposure,
age = age
)
})
units <- c(pressure = "mmHg", exposure = "mg", age = "years")
spec <- cttiR::study_spec(
study_id = "synthetic_association",
name = "Synthetic association example",
question = "How is pressure associated with exposure after adjusting for age?",
population = "Forty independently generated synthetic observations",
observation_id = "observation_id",
outcome = list(name = "pressure", type = "continuous", unit = "mmHg"),
exposure = list(name = "exposure", type = "continuous", unit = "mg"),
covariates = list(list(name = "age", type = "continuous", unit = "years")),
research = list(domain = "clinical", data_origin = "primary",
design = "observational")
)
cttiR::study_validate(spec, data, units)The axes have separate meanings: clinical controls the
research-domain colour, primary declares newly generated
data, and observational records the design. An existing
dataset would use secondary data origin without becoming an
evidence-synthesis project. The strict profile uses clinical red
#C8102E here.
Missing values, mismatching units and duplicate observation IDs stop validation. The recipe also rejects rank-deficient or degenerate fits; it does not silently exclude rows or select covariates from p-values. A direct numerical preview is:
result <- cttiR::study_analyze(spec, data, units)
result$coefficients
#> term estimate std_error statistic p_value conf_low
#> 1 (Intercept) 111.8269723 3.10332209 36.034601 2.032613e-30 105.539044422
#> 2 exposure 2.0513770 0.25872166 7.928896 1.703973e-09 1.527157167
#> 3 age 0.1232741 0.06481734 1.901870 6.499555e-02 -0.008058253
#> conf_high
#> 1 118.1149001
#> 2 2.5755969
#> 3 0.2546065This preview creates no project and no persisted execution receipt. Diagnostics and scientific assumptions still need review.
The following steps are explicit and are not run while this vignette
builds. Provision an installed external library containing cttiR,
reflowR with the strict composition API, workflowr and their
dependencies. study_dependency_lock() records the installed
R and dependency versions; it does not install packages or prove their
acquisition origins.
Compilation creates a separate Git repository and stages only the generated analysis Rmd templates. It creates no commit and stages no study data or results. Reports therefore show these new sources as uncommitted. Rendering refuses ambiguous source status instead of borrowing an enclosing repository’s history.
Use a new project path below an existing physical directory. The strict profile rejects symbolic links in the path. For an intentional temporary demonstration, resolve the known temporary parent before choosing the new child path:
directory <- tempfile("strict-study-", tmpdir = normalizePath(tempdir()))
compiled <- cttiR::study_project(
directory, spec, data, cttiR::study_dependency_lock(),
author = "Research group", units = units, seed = 20261016L
)
analyzed <- cttiR::study_run(compiled$directory, compiled$declaration)
reported <- cttiR::study_render(analyzed$directory, analyzed$declaration)
validation <- cttiR::study_validate_project(
reported$directory, reported$declaration, require_render = TRUE
)
stopifnot(validation$valid, !validation$scientific_approval)Retain the returned declarations outside the project in a trusted location. Each successful step returns the declaration required by the next step. Do not recover that authority from editable files inside the project. The project fixes eleven stage locations and a root index; inapplicable stages carry explicit reasons. Raw inputs are read-only and separate from derived outputs. This recipe marks sensitivity and exploratory work inapplicable because neither is prespecified.
study_run() writes numerical results and a receipt
binding the declared inputs, controls and outputs.
study_render() invokes genuine workflowr rendering in a
clean child R session and presents those recorded results. It does not
fit the model again. Input, code, environment or output changes
invalidate the matching checks. Preserve the existing project and
receipts; compile a new project for a new analysis rather than
overwriting recorded output.
When retaining a copy, preserve the read-only raw-data directory and file modes as well as file contents, and validate the copy against the external declaration. A copy operation that makes the raw directory writable fails strict validation.
Inspect docs/index.html and the stage pages. A valid
report demonstrates the checked synthetic workflow and its recorded
artifacts. It does not authorize a real study, establish legal
compliance, select a local model, commit files or publish the
report.