This release adds an opt-in plotting layer, fixes bugs surfaced by the package’s first field deployment, and redesigns the survey-taking experience. ggplot2 joins Suggests; hard dependencies are unchanged.
plots argument on run_analysis_plan()
(default FALSE). When TRUE, supported analysis
blocks return a ggplot object in $plot: bar charts for
frequency and chi-square blocks, and scatter plots with a regression
overlay for correlation and regression blocks.theme_surveyframe(), a
publication-oriented ggplot2 theme with an accessible fixed-order series
palette. All plots use it.$table data frame ready
for knitr::kable(); the HTML report shows these tables
automatically.item__option = 1 for the top choice), so ranks are
directly analysable. Multiple-choice items likewise export one 0/1
column per option instead of a single comma-joined column.
read_responses() accepts the expanded columns for ranking,
matrix, and multiple-choice items without warnings.render_report() now attaches each analysis block’s
chart directly under its result table, in both the Quarto and internal
HTML report paths, instead of tables and plots appearing in separate
places.read_sheet_responses() gains a meta_cols
argument for extra sheet columns a host application appends, and
SurveyStudio’s dashboard now computes completion times from imported
sheet responses.sem_lavaan_syntax() turns free-text path labels into
valid lavaan parameter names (a label starting “H1:” becomes the
parameter H1).seminr_syntax() output loads seminr and uses
summary() accessors, so the generated code runs as
pasted.run_analysis_plan() accepts pls_sem as an
alias for seminr_syntax..sframe verifies and reports its SHA-256
integrity status.This release corrects the package citation, completes the S3 method surface for the component classes, and improves the graphical tools and the HTML report. It adds no new exported functions, no new statistical methods, and no new bundled datasets.
inst/CITATION now reports the correct package title and
reads the version dynamically from the package metadata, so the citation
no longer pins an old version or an outdated title.print(), format(), and
summary() methods for the component classes
sf_choices, sf_item, sf_scale,
sf_branch, sf_check, and
sf_model, so each class now has a visible, documented S3
surface.lavaan is declared in Suggests. It is used
only to fit the syntax produced by cfa_syntax(). The
package itself generates syntax and never requires lavaan
to be installed.export_static_survey() and
export_google_sheet().render_report() renders reliably through Quarto when it
is installed. A path defect that made the Quarto render fail and fall
back to the plain internal output is fixed.This is a patch release. It fixes the static-survey to Google Sheets to R collection loop, repairs a serialisation defect, and improves the first-time user experience. There are no new exported functions, no new statistical methods, and no new bundled datasets.
export_static_survey() now renders the header logo and
institution name from render$header, so exported surveys
match the Shiny renderer and the builder preview.export_static_survey() now falls back to the
instrument’s render$google_sheets_endpoint when
endpoint_url is not supplied, so a Google Sheets endpoint
set in the builder is honoured on export.respondent_id, matching the Google Apps Script
collector and read_responses(). The collection round-trip
now preserves the identifier.export_google_sheet() now includes matrix sub-item
columns (item_id__sub) in the Apps Script header row, so
matrix answers are stored in the Sheet.read_sheet_responses() now declares
started_at as a meta column and no longer raises a warning
on every read.image/png, image/jpeg,
image/gif), so JPEG and GIF logos display correctly in the
builder, the Shiny renderer, and the static export.write_sframe() now strips list-level names from the
item, choice, scale, branching, check, and model collections before
serialisation. Instruments built with Map() or other
helpers that attach element names (for example, using item IDs as names)
previously serialised those collections as keyed JSON objects rather
than arrays. This produced a hash mismatch and an integrity error on
read_sframe(). Saved instruments now round-trip correctly
regardless of how the component lists were constructed.sframe object. The message points the user to
sf_instrument() and read_sframe() instead of
showing a raw inherits() assertion failure.reliability_report() no longer prints
psych internal warnings to the console. McDonald’s omega is
skipped silently for scales with fewer than three items, where the
statistic is not meaningful.run_analysis_plan() when no
analysis plan is present now describes both the programmatic route
(instrument$analysis_plan) and the visual SurveyBuilder
route.surveyframe.Rmd) as an
end-to-end worked example: design the questionnaire, export it as a
hosted survey with a Google Sheets backend, collect responses, score
them, run the analysis plan, and render a report. The results section
uses simulated responses so the vignette builds offline; a single
read_sheet_responses() call connects the same workflow to
live responses. The questionnaire and concept are adopted from
Sharafuddin, Madhavan, and Wangtueai (2024, Administrative
Sciences, 14(11), 273, doi:10.3390/admsci14110273), with generic destination
wording so the example transfers to any tourism services context.sf_instrument() examples now include a complete
analysis_plan block.install.packages("surveyframe"), adds a short path for
users who already have a response CSV, and points to
browseVignettes("surveyframe").The first CRAN release of the full workflow: a typed instrument object carrying the questions, the analysis plan, and the measurement model, with deployment, collection, analysis, and reporting built around it.
variables/test analysis blocks. New plans can
store family, method, roles,
options, hypotheses,
decision_rule, reporting_references,
status, and requires_data.descriptives_report(), missing_data_report(),
assumption_report(), posthoc_report(),
validity_report(), and
sample_size_plan().run_analysis_plan() to dispatch the v0.3
method registry, including descriptives, missing data, sparse-table
tests, related-sample tests, Kendall and partial correlations, two-way
ANOVA, ANCOVA, repeated ANOVA, ordinal and multinomial logistic
regression, mediation, moderation, and model-syntax output.sf_construct(),
sf_path(), sf_covariance(),
sf_indirect(), sf_model(),
validate_model(), model_json(),
add_model(), efa_solution(),
efa_syntax(), cfa_lavaan_syntax(),
sem_lavaan_syntax(), seminr_syntax(), and
model_report_template(). Syntax generation does not require
lavaan or seminr.cfa_syntax() remains available as a backward-compatible
wrapper around cfa_lavaan_syntax().Added export_static_survey(). This produces a
single, self-contained HTML file that runs the survey in any modern
browser without a Shiny server or an internet connection. All thirteen
item types are fully rendered (Likert, single choice, multiple choice,
matrix, numeric, text, long text, date, slider, rating, ranking, section
break, text block). Branching logic, required-field validation, a
progress bar, welcome and thank-you pages are all handled in client-side
JavaScript. On submission the browser downloads a per-respondent CSV
file. An optional endpoint_url argument adds a parallel
JSON POST to any serverless endpoint (Google Apps Script, Netlify
function, etc.).
The exported file is suitable for hosting on GitHub Pages, Netlify, or any static file server, and can also be shared directly as an e-mail attachment and opened from disk.
The SHA-256 hash written into .sframe files by
write_sframe() and by the SurveyBuilder HTML is computed
using the same canonicalisation algorithm, so instruments round-trip
correctly between the browser and R.
Added launch_dashboard(). Opens a five-panel Shiny
dashboard for exploring collected response data alongside the instrument
definition, without modifying either. The panels are: Overview (response
count, date range, instrument metadata), Items (per-item bar charts,
histograms, and frequency tables), Scales (scale score distributions
with mean overlay), Quality (attention-check pass rates), and Raw data
(a scrollable response table with CSV download).
When called without arguments the dashboard loads the bundled tourism
services demo. When called with a user-supplied instrument and no
responses argument, it opens in metadata-only mode showing
instrument structure.
Added sframe_demo_data(),
sframe_input_types_demo_data(),
launch_builder_demo(), launch_studio_demo(),
and launch_dashboard_demo() for CRAN-safe examples,
training, and local GUI testing.
Added a bundled input-types demo instrument and simulated response dataset for testing SurveyBuilder, SurveyStudio, the dashboard, and all supported item controls.
launch_studio() now accepts preloaded instruments,
response data frames, CSV response paths, initial screen selection,
host, port, and browser control. SurveyStudio reads these preloaded
values during startup.
Added survey_module_ui() and
survey_module_server(). These allow a survey to be embedded
inside a larger Shiny application as a first-class module.
survey_module_server() returns a reactive that
holds NULL until the form is submitted, then returns the
response as a named list keyed by item ID.
ui <- fluidPage(survey_module_ui("s1"))
server <- function(input, output, session) {
resp <- survey_module_server("s1", instrument = instr)
observeEvent(resp(), { saveRDS(resp(), "response.rds") })
}An optional on_submit callback fires immediately on
submission, before any observeEvent() elsewhere in the
app.
run_analysis_plan() now implements four additional tests
used by the SurveyBuilder’s test dropdown:
anova_one: One-way ANOVA with eta-squared effect size.
When the result is significant and there are more than two groups, Tukey
HSD post-hoc output is included in the result object.t_test_pair: Paired-samples t-test with Cohen’s
d_z.wilcoxon_pair: Wilcoxon signed-rank test with r effect
size.regression_logistic_binary: Binary logistic regression
with McFadden R-squared and an overall model chi-square test. The full
coefficient table is returned for interpretation.All four runners produce an APA-formatted summary string and an
interpretation prompt field to guide write-up.
write_sframe() validates the instrument and writes
the validated object, preserving meta$validated = TRUE in
the saved .sframe file.
.sframe serialisation now includes a
models field and continues to read older
.sframe files where models is absent.
read_responses() no longer requires display-only
items such as section_break and text_block to
appear as response columns.
validate_sframe() now checks model references,
analysis-plan roles, invalid model IDs, duplicate model IDs, and model
indicator/path integrity.
launch_builder(open = TRUE) opens the SurveyBuilder
HTML in the system’s default browser via
utils::browseURL().
R/studio_builder.R contains three fully implemented
internal functions (sframe_builder_empty_state,
sframe_builder_state_from_instrument,
sframe_builder_validate_draft) used by SurveyStudio startup
and draft validation.
SHA-256 hashing in the SurveyBuilder HTML includes a
pure-JavaScript fallback for environments where
crypto.subtle is unavailable on file://
origins, including common Firefox file:// configurations.
Saving a .sframe file from the builder now always
succeeds.
The SurveyBuilder’s rqSuggest box now appears with
an icon and a plain-language recommendation when two or more variables
are selected in the RQ modal.
The undo and redo buttons in the SurveyBuilder topbar are now correctly disabled when their respective history stacks are empty.
export_google_sheet() now writes Google Apps Script
using JSON-encoded JavaScript literals instead of interpolating
instrument metadata directly into executable code. The generated
endpoint also rejects missing, over-large, and non-object JSON POST
bodies..sframe and .csv files by extension, size, and
text-content checks before passing them to import functions.read_sframe() now validates the top-level
.sframe payload structure before hash verification and
object reconstruction.on.exit() even when rendering fails.validate_sframe(), score_scales(),
codebook_report(), cfa_syntax(), and
launch_builder(open = FALSE) have fully runnable
examples.launch_builder_demo(),
launch_studio_demo(), and
launch_dashboard_demo()) open in the browser with the demo
instrument, scales, and analysis plan preloaded, so no manual file
loading is needed.demo("survey")) walks
through the whole workflow with step-by-step prompts.sf_instrument(),
sf_item(), sf_choices(),
sf_scale().write_sframe(),
read_sframe() with SHA-256 integrity checking.render_survey().launch_builder().read_responses().