
Check a YAML study specification and list every problem
Source:R/tteplan_check_spec.R
tteplan_check_spec.RdReads one specification file and returns a table with one row per problem. It never stops on a bad specification, so a caller can check many files in one pass.
Value
A data.table::data.table() with one row per problem, and three
character columns:
pathThe normalised key path of the problem, for example
$/study/implementation/version. A problem with the whole file has the path$.kindThe problem kind. The Details section lists the twelve kinds.
messageWhat is wrong, and the repair where swereg knows it.
The table has zero rows when the checker finds no problem.
Details
The checker reports twelve kinds of problem:
unreadableThe file is missing, is not valid UTF-8, or is not valid YAML. This row is the only row, because the checker has no parsed specification to check.
undeclared_keyThe schema does not declare the key path. The message lists the keys that the context accepts.
retired_keyThe schema refuses the key path. The message names the replacement.
invalid_enrollment_idAn enrollment has no
id, or itsidis not one non-empty character string or one number. The checker refuses a sequence, a mapping, and an empty or whitespace-only string. It writes one row for each such enrollment.duplicate_enrollment_idTwo or more enrollments carry the same
id. The checker writes one row for each repeated id. It compares only the ids that give noinvalid_enrollment_idrow.version_mismatchThe file name has the form
spec_vNNN.yaml, andstudy$implementation$versionis missing or is notvNNN. The checker skips this check for every other file name.outcome_selecting_exclusionAn exclusion criterion has the window
lifetime_before_and_after_baselineon a variable of an outcome. That window reads the weeks after time zero, so the criterion selects on the follow-up outcome. The checker writes one row for each criterion and outcome. The checker reads the globalexclusion_criteriaand each enrollment'sadditional_exclusion.enrollment_familyAn enrollment's
familyis not one non-empty character string. Or some enrollments setfamilyand others do not. When one enrollment setsfamily, every enrollment MUST set it. The checker writes one row for each bad value, and one row that names the enrollments without afamily.enrollment_rule_exemptAn enrollment sets
minimum_events_rule_exemptto a value that is not one logical,trueorfalse. The checker writes one row for each such enrollment, and the message names the enrollment id.feasibility_follow_up_weeksThe top-level key
feasibility_follow_up_weeksis not one positive whole number of weeks. The checker writes one row, and the message names the key.follow_up_only_enrollmentsA
follow_upentry setsonly_enrollmentsto a bad value. The value MUST be a non-empty list of enrollment ids. A single id is a list of one. The list MUST NOT repeat an id, and each string MUST be theidof an enrollment. The checker writes one row for each bad entry. The message names the follow-up label and the bad value.read_errortteplan_read_spec()stops after its key gate. The message is the message of that error.
The checker reports every undeclared key path and every retired key path.
tteplan_read_spec() reports them too, but stops after them. The checker
calls tteplan_read_spec() only when no key path is undeclared or retired,
because the key gate stops it first. tteplan_read_spec() stops at its
first problem after the key gate, so a table holds at most one
read_error row.
A warning from tteplan_read_spec(), for example on an open question,
reaches the caller unchanged.
See also
tteplan_read_spec(), which stops at the first problem, and
vignette("tte-spec-schema", package = "swereg") for the key paths the
schema declares.
Examples
spec_dir <- tempfile()
dir.create(spec_dir)
spec_path <- file.path(spec_dir, "spec_v002.yaml")
writeLines(
c(
"study:",
" colour: blue",
" implementation:",
" project_prefix: example",
" version: v001"
),
spec_path
)
tteplan_check_spec(spec_path)
#> path kind
#> <char> <char>
#> 1: $/study/colour undeclared_key
#> 2: $/study/implementation/version version_mismatch
#> message
#> <char>
#> 1: Unknown key 'colour'. $/study accepts: description, design, implementation, principal_investigator, title.
#> 2: study$implementation$version is 'v001', and the file name spec_v002.yaml gives 'v002'.
unlink(spec_dir, recursive = TRUE)