--- title: "01 — SSPICE overview and workflow" author: "Pierpaolo Massoli" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{01 — SSPICE overview and workflow} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>", eval = FALSE) ``` > Operational examples assume that the SSPICE project root is the working directory. Operational chunks are not executed when building the vignette because they require the project data. Standalone chunks explicitly marked `eval=TRUE` are exceptions. # Why SSPICE SSPICE stands for **Systematic Skip-Pattern Integrity and Consistency Engine**. SSPICE represents the logical dependencies of a questionnaire using a directed acyclic graph (DAG). It uses this graph to check response paths, localize inconsistencies, construct domains and formal rules, correct erroneous records, and assess the results. Missing values have a structural meaning: an inactive question must be blank, whereas an active question may require a response. # Operational workflow | Stage | Main input | Result | |:--|:--|:--| | 01 | Routing metadata | Canonical DAG | | 02–03 | Data, metadata and external sources | Prepared data and routing check | | 04–05 | DAG and item mapping | Domains, rules and Horn validation | | 06 | Prepared data and routing check | Violation localization | | 07–08 | DAG | Synthetic data and admissible-pattern count | | 09 | Prepared data, routing and semantic-edit metadata | Extended data and extended DAG | | 10 | Extended data and extended DAG | Correction of erroneous records | | 11 | Correction results and original extended data | Quality report | The operational steps are in `scripts/`. `00_config.R` defines paths and options; `01_build_DAG.R` builds the graph; `02_prepare_data.R` prepares records; `03_run_routing_check.R` checks routing; and `04_create_VARDOM_and_RULES.R` produces constraints. `05_validate_horn_theory.R` and `06_validate_violation_localization.R` perform the corresponding validations. `09_build_extended_DAG.R`, `10_correct_data.R` and `11_correction_quality_report.R` complete the correction and assessment workflow. Scripts 07 and 08 respectively generate synthetic data and count admissible patterns. ```{r workflow} source(file.path("scripts", "00_config.R")) source(file.path("scripts", "01_build_DAG.R")) source(file.path("scripts", "02_prepare_data.R")) source(file.path("scripts", "03_run_routing_check.R")) ``` Run the steps in order and inspect intermediate outputs before starting correction. Metadata quality determines the quality of the diagnoses. # Reading order 1. [Metadata and external sources](metadati-02.html). 2. [Building the routing file](routing-02b.html): fields, types, conditional and unconditional jumps, and OR/XOR groups. 3. [Item mapping](item-mapping-02c.html): observed codes, structural codes, modal positions, jumps, correction and semantic predicates. 4. [Building the DAG](dag-03.html) and [data preparation and checks](controlli-04.html). 5. [Domains and rules](regole-05.html). 6. [Correction](correzione-06.html) and [correction quality](qualita-correzione-07.html). Instructions such as `source("scripts/...")` refer to a source-project copy containing the required scripts and data. Installing the package does not recreate the PROJECT directory. The routing guide also contains small examples using `SSPICE::build_DAG()` directly, independently of the application data. # Standalone first run This example needs the installed package only. GATE = 1 skips DETAIL; GATE = 2 requires DETAIL. Record 3 deliberately answers a skipped question. The first two records are admissible donors. No source files are overwritten. ```{r standalone-workflow, eval=TRUE} local({ routes <- read.table(text = paste( "ID;1;1;9999;0;0;.;.", "GATE;2;1;2;0;1;1;END", "DETAIL;2;1;2;0;0;.;.", "END;1;1;1;0;0;.;.", sep = "\n"), sep = ";", header = FALSE, na.strings = ".") dag <- SSPICE::build_DAG(routes, analyze = FALSE) raw <- data.frame(ID = 1:3, GATE = c(1, 2, 1), DETAIL = c(NA, 1, 1), END = c(1, 1, 1)) prepared <- SSPICE::prepare_data(raw, dag) # The current checker requires a mapping file, even with no recoding. mapping <- tempfile(fileext = ".csv") on.exit(unlink(mapping), add = TRUE) write.csv(data.frame(varname = character(), item_route = numeric(), item_dataset = numeric()), mapping, row.names = FALSE) check <- SSPICE::routing_check( prepared$data, dag$routes_numeric, dag$Bt, "ID", basename(mapping), dirname(mapping) ) print(check$full_report) stopifnot(setequal(unique(check$full_report$ID), 3)) # Only the erroneous row is sent to correction. Donors are fixed. result <- SSPICE::correct_data( data = prepared$data[3, , drop = FALSE], dag = dag, record_id = "ID", donor_data = prepared$data[1:2, , drop = FALSE], items_mapping_file = mapping, control = SSPICE::correction_control( seed = 123L, max_iterations = 20L, use_parallel = FALSE ) ) print(result$corrected_data) print(result$record_summary) print(result$unresolved_records) stopifnot(identical(result$corrected_data$ID, prepared$data$ID[3])) # Resolution is read from the final checks, not assumed from termination. print(result$final_routing_check$full_report) }) ``` The error report should identify record 3. The correction output remains in the prepared representation. Inspect `record_summary$resolved` and `unresolved_records`; a stochastic search need not resolve every input. The full project workflow also includes semantic edits and exogenous sources. Its recorded configuration, input files and output directories are required to reproduce a run; the small example is not a reproduction of the paper.