--- title: "Questionnaires, Structure, and Codebooks" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Questionnaires, Structure, and Codebooks} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) library(SurveySolutionsAPIv2) library(data.table) # Load pre-rendered demo data for offline vignette compilation ext_st <- system.file("extdata", "demo_questionnaire_structure.rds", package = "SurveySolutionsAPIv2") if (file.exists(ext_st)) { quest_struct <- readRDS(ext_st) } else { quest_struct <- list( q = data.table(), val = data.table(), v = data.table(), answers = data.table() ) } ``` ## Introduction Survey Solutions questionnaires are sophisticated hierarchical documents comprising sections, multi-level rosters, conditional skip patterns, inline validation rules, static text instructions, and calculated variables. With **`SurveySolutionsAPIv2`**, you can extract the entire questionnaire specification in milliseconds into clean, normalized flat tables. This enables automated codebook generation, survey documentation, and pre-fieldwork verification of routing logic. --- ## 1. Extracting Questionnaire Structure To extract the structure of a questionnaire, supply the `QuestionnaireId` (GUID), `version`, and specify `operation.type = "structure"`: ```r library(SurveySolutionsAPIv2) # Extract questionnaire structure quest_struct <- suso_getQuestDetails( questID = "17a9fa22-1ef6-46d2-8c30-426aa876f273", version = 1, operation.type = "structure", include_raw = FALSE ) ``` The function returns a named list with **4 structured `data.table` elements**: ```{r} names(quest_struct) ``` - **`q`**: Question, roster, and variable metadata. - **`val`**: Validation rules, expressions, messages, and severity labels. - **`v`**: Backward-compatible alias for `val`. - **`answers`**: Categorical question answer codes, labels, and category mapping. --- ## 2. Question Hierarchy and Metadata (`q`) The `q` table provides an atomic, row-by-row flat representation of every item in the questionnaire: ```{r} dim(quest_struct$q) ``` ### Inspecting Essential Columns Key columns include: - **`intID`**: Hierarchical index formatted as clean dot-separated levels (e.g. `01`, `01.02`, `01.02.04`). - **`VariableName`**: Variable name used during data export. - **`QuestionText`**: Formatted question prompt or label. - **`type`**: Element type (`SingleQuestion`, `NumericQuestion`, `TextQuestion`, `GpsCoordinateQuestion`, `AreaQuestion`, `Variable`, `StaticText`, etc.). - **`SectionTitle`** & **`RosterTitle`**: Contextual hierarchy indicating parent sections and rosters. ```{r} # Display a sample of questions quest_struct$q[1:6, .(intID, VariableName, type, QuestionText = substr(QuestionText, 1, 40))] ``` ### Static Text and Calculated Variables Unlike standard survey tools, Survey Solutions supports static text blocks and calculated variables (derived formulas). `SurveySolutionsAPIv2` captures both without data loss: ```r # Calculated variables and expressions calc_vars <- quest_struct$q[type == "Variable", .(VariableName, Expression, VariableType, VariableLabel)] ``` ```{r, echo = FALSE} quest_struct$q[type == "Variable", .(VariableName, Expression = substr(Expression, 1, 35), VariableType)][1:5] ``` --- ## 3. Skip Patterns and Routing Logic Routing conditions (`ConditionExpression`) define when a question or entire roster is visible or skipped: ```{r} # Questions with routing conditions conditions <- quest_struct$q[!is.na(ConditionExpression) & nchar(ConditionExpression) > 0, .(VariableName, ConditionExpression = substr(ConditionExpression, 1, 50))] head(conditions, 5) ``` Survey designers can use this table to verify that skip patterns reference valid prior variables before piloting. --- ## 4. Validation Rules and Severity (`val`) The `val` table extracts all Designer validation expressions and their associated error messages: ```{r} dim(quest_struct$val) ``` Each validation record provides: - **`VariableName`**: The target variable being validated. - **`Expression`**: The C# boolean expression that must evaluate to `true`. - **`Message`**: The message presented to the enumerator if the expression evaluates to `false`. - **`Severity`**: `0` for Error (blocks completion), `1` for Warning (can be acknowledged). - **`SeverityLabel`**: Human-readable `"Error"` or `"Warning"`. ```{r} # Inspect validation rules quest_struct$val[1:5, .(VariableName, Expression = substr(Expression, 1, 30), SeverityLabel, Message = substr(Message, 1, 35))] ``` --- ## 5. Generating Codebooks (`answers`) For categorical questions (single-select and multi-select), the `answers` table captures all answer options: ```{r} dim(quest_struct$answers) ``` Each record contains: - **`VariableName`**: Parent variable name. - **`AnswerValue`**: Internal key. - **`AnswerCode`**: Numeric code exported in datasets. - **`AnswerText`**: Label shown to respondents and enumerators. - **`CategoriesId`** & **`CategoryName`**: Reusable category catalogue reference if applicable. ```{r} # View codebook options for a sample question sample_var <- quest_struct$answers[!is.na(AnswerText)][1, VariableName] quest_struct$answers[VariableName == sample_var, .(VariableName, AnswerCode, AnswerText)] ``` --- ## 6. Clean Flat Tables vs Raw JSON By default, `include_raw = FALSE` produces pure atomic tables with no list-columns. This ensures direct compatibility with file writers like `data.table::fwrite()`: ```r # Export directly to CSV without list-column serialization errors data.table::fwrite(quest_struct$q, "questionnaire_metadata.csv") data.table::fwrite(quest_struct$answers, "questionnaire_codebook.csv") ``` If you require low-level access to the original JSON node definitions (such as custom properties or raw translation tables), set `include_raw = TRUE`: ```r # Retain raw ..JSON list column raw_struct <- suso_getQuestDetails( questID = "17a9fa22-1ef6-46d2-8c30-426aa876f273", version = 1, operation.type = "structure", include_raw = TRUE ) # Access raw properties of the 10th node raw_node <- raw_struct$q$..JSON[[10]] ``` --- ## 7. Questionnaire Settings: Audio & Criticality ### Audio Audit Recording Survey Solutions supports background audio recording audits for quality assurance: ```r # Query current audio recording setting audio_setting <- suso_questRecordAudio( questID = "17a9fa22-1ef6-46d2-8c30-426aa876f273", version = 1 ) # Enable background audio recording suso_questRecordAudio( questID = "17a9fa22-1ef6-46d2-8c30-426aa876f273", version = 1, enabled = TRUE ) ``` ### Criticality Level You can programmatically retrieve or enforce validation criticality: ```r # Get current criticality level suso_questCriticalityLevel( questID = "17a9fa22-1ef6-46d2-8c30-426aa876f273", version = 1 ) # Set criticality level to Warn suso_questCriticalityLevel( questID = "17a9fa22-1ef6-46d2-8c30-426aa876f273", version = 1, level = "Warn" ) ```