3  Reading Objectives

Course input consists of descriptive metadata, course objectives, and session objectives. Assessment items may be included in the same YAML file or supplied separately. The readers return named lists that can be passed to plan_mapping() and map_curriculum().

3.1 Course files

course_name: DEMO 101
title: Introduction to Data Analysis
term: Example term

objectives:
  - Summarize a numerical dataset using descriptive statistics.
  - Justify a chart choice for a specified analytical question.

sessions:
  session_01:
    - Calculate the median of a supplied numerical vector.
    - Compute the interquartile range of a supplied numerical vector.
  session_02:
    - Construct a histogram of a supplied continuous variable.
library(curriculum)

course <- read_objectives("objectives.yaml")
length(course[["objectives"]])
lengths(course[["sessions"]])

objectives is a character vector. sessions is a named list of character vectors. The optional assessments block has the same grouped structure. course_name, title, and term supply descriptive metadata.

Use read_course() to combine objectives and a separate assessment file:

course <- read_course("objectives.yaml", "assessments.yaml")

If the objectives file already contains assessments, supply that file alone. read_course() rejects two nonempty assessment sources.

3.1.1 Stable identifiers

Session keys and item positions contribute to generated identifiers. With course_id = "demo", the first objective in session_01 has the identifier demo.S01.SO.01. Keys of the form session_NN are shortened to SNN; other keys retain their text in the session component.

Keep keys, item order, and course_id consistent when comparing runs. Inserting or reordering objectives changes position-based identifiers. A comparison of revised course content therefore requires review of the identifier matches.

3.1.2 Source material

Session objectives and assessment items may include source records. A registry under sources defines references that can be reused by individual items:

sources:
  course_notes:
    type: notes
    title: Data Analysis Course Notes

sessions:
  session_01:
    - text: Calculate the median of a supplied numerical vector.
      source:
        ref: course_notes
        locator: Section 2.1
    - Compute the interquartile range of a supplied numerical vector.

An item may contain plain text or a mapping with text and source. A source can be a citation string, one record, or a list of records. Fields in the item record override fields inherited through ref. An undeclared reference is an error. Quote YAML strings containing a colon followed by a space.

read_objectives() stores resolved records in session_sources and assessment_sources, aligned with the corresponding item positions. Alignment and classification use the item text; source records provide context for editorial review. Source annotations are supported for sessions and assessments; course objectives remain plain character strings.

3.2 Spreadsheet input

read_objectives_table() reads a wide table whose first column contains course objectives and whose remaining columns contain session objectives. Columns may have different numbers of populated cells.

Course objectives Week 1 Week 2
Summarize a numerical dataset. Calculate a median. Construct a histogram.
Justify a chart choice. Compute an interquartile range.
objectives <- read_objectives_table(
  "objectives.xlsx",
  course_name = "DEMO 101",
  title = "Introduction to Data Analysis",
  term = "Example term",
  sheet = "Objectives"
)

The reader supports .xlsx through readxl, and .csv and .tsv through utils. Convert legacy .xls files to a supported format first. Supply course metadata through the function arguments.

The reader trims leading and trailing whitespace and removes empty cells. It assigns session keys in column order. Original session-column headers are stored in attr(objectives[["sessions"]], "headers") and included as comments by write_objectives().

3.2.1 Import findings

Empty session columns are omitted with a warning. Identical populated columns and repeated objectives remain in the result for review. By default, the reader also runs check_objectives() and reports findings using spreadsheet headers. check = FALSE disables that additional check. Import does not revise the substantive wording of an objective.

3.3 Structural and text checks

findings <- check_objectives(objectives, course_id = "demo")
findings

The returned data frame contains check, severity, scope, id, id_b, text, and detail. Findings are ordered by severity. A result with no findings has zero rows and is returned invisibly.

Check Interpretation
structure, empty_session Missing, malformed, or empty objective groups
empty_text Empty or whitespace-only text
session_key, duplicate_session_key Session naming or identifier conflicts
whitespace, numbering Formatting retained in the text supplied to a model
truncated, short_text Text that may be incomplete or insufficiently specified
duplicate_objective, identical_sessions Exact duplication within the supplied objectives
shared_text Identical text at the course and session levels
redundancy High token overlap between objective statements

These checks identify patterns for review. For example, repeated content may be intentional, and a truncation flag does not establish that text is missing. check_objectives() leaves the input unchanged and returns structural problems as findings. Invalid function arguments may still raise errors.

The default mapping workflow stops on findings with severity "error" before calling a model. With check = FALSE, the mapping workflow skips this check and does not populate its findings; ordinary argument validation still applies.

Token-overlap checking can be disabled with check_objectives(objectives, redundancy_threshold = NULL). After classification or mapping, redundant_objectives() accepts a Classification or CurriculumMapping object and returns a separate overlap table. It does not accept the raw course list.

3.4 Writing objectives

write_objectives(objectives, "objectives.yaml")
cat(write_objectives(objectives))

Supplying a file writes YAML; omitting it returns the YAML text. write_objectives() serializes descriptive metadata, course objectives, and session objectives from the spreadsheet-oriented list. It is not a general round-trip serializer for a complete course with assessments and source annotations. Preserve those fields separately when editing annotated YAML.

3.5 Editorial revision

Review objectives for the performance, subject matter, conditions, and criteria they specify. The Bloom’s taxonomy chapter provides examples. Keep the imported wording and revised objectives in separate files when the distinction is relevant to the analysis. Record substantive changes, including objectives that were split, combined, added, or removed.

Source material can inform revision, but the final statement should contain enough context for an independent reader to interpret its intended performance. Run structural checks again after editing, then use the reviewed file for planning and mapping.

© 2026 E.D. Gennatas