CEDAR Analytics

A clearer view of courses, programs, and student pathways

CEDAR brings enrollment, program, course, and outcome data into one workspace so departments can move from a question to a defensible next step.

Core values
Transparency
Accessibility
Practicality

Department Views

Analysis Workspaces

Registration Tools

Explore Tools

Admin Tools

Feature Spotlight

Course titles matter for topics courses

In Pathways > Course to Major, course + instructor signals keep course titles with the course number so topics courses do not collapse into one generic row.

Open Pathways
What's New

Recent features worth a look

View all updates
Aug 2026

Methods are open to inspection

Non-obvious calculations now carry concise explanations and links to user documentation, methodology details, and the code that implements them.

Aug 2026

Grade rates stop at the last graded term

DFW and other grade-based rates now end at the most recent term with grades actually posted, instead of counting a term whose grades have not landed. That term used to read as a dramatic improvement.

Aug 2026

Course timing is measured, not assumed

Pathways Course Timing now defaults to Classification, the one axis that works for every student. The credit axes exclude students whose record starts before the data does, and say how many were set aside and why.

Aug 2026

Gen Ed for your graduates

Dept Trends Gen Ed now shows when your graduates took Gen Ed courses, which ones, and how your own unit's Gen Ed offerings fit into their path.

Dept Dashboard

Headcount trends, enrollment patterns, and course activity for a single semester.

Select a department, then click Gather Data to load its dashboard.

Students

Selected-term headcount and recent movement worth noticing.

Enrollment Signals

Current-term enrollment signals for the selected department and campus. Above/below average compares to the recent same-term average: last 3 years, with at least 2 prior same-season offerings.

Above Average This Term

Courses running higher than the recent average.

Below Average This Term

Courses running lower than the recent average.

Early Drop Watch

Courses with more pre-census drops than their own recent pattern.

Late Drop Watch

Courses with more post-census drops than their own recent pattern.

Credit Hour Shifts

Course-level SCH this term compared with the recent same-season pattern.

Low Enrollment Review

Selected-term sections under the low-enrollment thresholds for associate dean and chair review. Uses the same low-enrollment helper as the Enrollment tab and omits green buffer rows.

High Waitlists

Selected-term courses where waitlist demand is already visible.

Course Activity

Quick flags for new, missing, and recurring offerings in the selected term.

New This Term

Courses whose course number and title have not appeared in the historical data. Topics courses count each distinct title separately.

Missing vs. Two Years Ago

Courses that ran in this same term type two years ago but are not scheduled this term.

Recurring Topics This Term

Topics courses running this term that have been offered at least twice before under the same course number and title.

Audience Shifts

Program overlap and course-audience shares that moved enough to notice this term. Dashboard threshold: at least 10 percentage points away from the prior three same-season terms, with enough students present. Full audience detail is in Dept Trends > Enrollment.

Dept Trends

Longitudinal department patterns in students, enrollment, degrees, credit hours, Gen Ed, and course outcomes.

Pathways

Define a student population, then explore course timing, roadblocks, sequences, and major changes. Institution-level Gen Ed patterns are in Explore > Gen Ed.

Population

Audits the student group you defined — how many students it includes, how they entered (first-time, transfer, pre-major), and how the focal / pre-major split breaks down. Read the coverage panel first: it says how much of each student's record this data can see, which bounds every timing view on the other subtabs. Pathways guide →

Roadblocks

Courses where failing costs your students more than it costs everyone else taking the same course. Pathways guide →

Some courses are hard for everyone. This table looks for something narrower: courses where failing costs your students more than it costs everyone else taking the same course.

For each course it asks four questions in order. Of your students who got a D/F/W, how many did not come back the next term? Of your students who passed, how many did not come back? The difference between those two is the Pop gap — what failing this course costs your students. Running the same comparison on every other student in the course gives the Baseline gap, and your gap minus theirs is the Excess gap. That last number is the signal the table is built on.

Impact multiplies the excess gap by how many of your students actually got a D/F/W, and sets the row order — so a wide gap affecting three students does not outrank a narrower one affecting forty.

A course everyone struggles in equally has a small excess gap no matter how high its failure rate, which is why a high DFW rate on its own does not put a course near the top. The last two columns carry those rates so you can tell a hard course from a course that pushes your students out.

What it cannot tell you is why. Students who fail a course differ from students who pass it in ways this data never sees — hours worked, what else they were carrying, what was happening at home. A high row is a course worth asking about, not a course proven to have caused anything.

Column guide
  • Course: course code.
  • Impact: positive excess gap multiplied by the number of population students with a DFW. Higher values balance severity and scale, and set the row order.
  • Excess gap: population stop-out gap minus baseline stop-out gap. This is the roadblock signal — how much worse a DFW goes for your students than for everyone else in the same course.
  • Pop gap: population DFW stop-out rate minus population pass stop-out rate.
  • Baseline gap: the same DFW-vs-pass gap among all non-population students in the course.
  • Pop DFW and Pop pass: population students in the DFW and passing groups.
  • DFW stop-out and Pass stop-out: share of each group that did not return the next fall or spring.
  • Pop DFW rate and Baseline DFW rate: context, not the ranking. How often your students fail the course versus everyone else in it. A high rate here is not by itself a roadblock — a course everyone struggles in equally is a hard course, not a course that pushes your students out.

Course Timing

Shows when students in your population typically take each course — by credits earned, enrolled term, or classification — so you can see the usual sequence and spot courses taken unusually early or late. Each axis answers a different question and states its own limits beneath the chart. Pathways guide →

Course Pairs

Surfaces common A→B course sequences: of students who took course A, what share later took course B? Useful for spotting de-facto prerequisites and popular follow-ons. Pairs more than the max term gap apart are excluded, and non-ongoing students count only through their last focal term. Course A enrollments are counted only where the data holds the full follow-up window, so recent terms don't deflate the rates. Pathways guide →

Course to Major

Looks for courses near the doorway into the major — which course-and-instructor groups are most often followed by later entry into the department, and, in the heatmaps, what students took before they first entered the unit. Descriptive signals, not causal claims. Pathways guide →
GEN ED

Course + Instructor Signals

The population defines the focal department and subject prefixes; this table then scans all enrolled students in those focal-subject courses — it is not limited by the Population scope dropdown. A student counts as entering only when their first major or pre-major record in this department appears after the course term. Same-term department records are excluded because the course did not clearly precede entry. By default the To term ends one regular term before the newest complete term — students enrolled more recently have had no time to enter the department, so including them deflates Entry %. The Courses Before Major Entry heatmaps use a different scope: selected-population students only.

Column guide
  • Campus — the campus that delivered the course.
  • Course — the course code.
  • Instructor — primary instructor of record for that section.
  • Eligible — registered students in that course + instructor group who did not already have a department major or pre-major before or during the course term.
  • Later entered — eligible students whose first department major or pre-major record appears after the course term.
  • Later major / pre-major — whether that first later department record was a full major or a pre-major.
  • Median terms — typical number of regular terms between the course and first later department record.
  • Entry % — Later entered ÷ Eligible.
  • % of Pool — this group’s Eligible count as a share of all distinct eligible students across all groups. It can sum to more than 100% because one student can take multiple courses.
  • Terms — how many distinct terms this instructor taught this course (indicates sample breadth).
Table: Course + Instructor Signals — all enrolled students in focal-subject courses, grouped by campus, course title, and instructor.
Courses Before Major Entry Show heatmaps

For students who entered the selected population, this shows courses taken before their first focal program record. T−1 is the prior regular term; summer is skipped by default. Empty cells did not meet the minimum-student threshold. Campus, level, Gen Ed, and date-range association filters do not apply to these heatmaps.

Courses from this unit


Courses from other departments

Major Changes

Shows when students enter the selected unit as pre-majors or full majors, when pre-majors become full majors, and when students leave for another major. Always-UNM and transfer students are shown separately where possible. Pathways guide →
Changes by Term
Arriving from
Leaving for

Inflow / Outflow by Major

One row per major. Arriving to counts students who switched into that major from somewhere else; leaving for elsewhere counts students who switched out of it. The same major can show up in both.


Common Pathways (from → to)

Each row is a specific from→to switch. Switches involving only a few students are hidden so individuals can't be identified. Median completed / attempted UNM credits come from class-list-derived observed credits through the term before the switch posted.


Reference Tables

Use these when you need to audit the summaries above. The movement table is aggregated; the change-events table is student-level.

Movement detail (aggregated) Rows behind the Enter / Convert / Leave movement cards, including rows excluded from headline cards.
Change events (student-level switches) Every individual primary-major switch behind the switch charts and tables.

Methodology

How every number on this tab is built, in order: how the student group is defined, then each analysis in turn. Written to be read against the results rather than before them — each section names the function that produces the figure. Pathways guide →

How These Analyses Work

This page documents exactly how each analysis is computed, derived directly from the source code. Use it to interpret results correctly and spot anomalies.

1. Building a Student Group

File: R/branches/population.R
Functions: build_population()get_focal_programs(), get_ongoing_ids(), get_graduated_ids(), get_switched_out_ids(), get_never_declared_ids(), get_entry_pathways(), classify_origin(), classify_entry_method(), classify_entry_status(), build_demographic_population()

A student population is built in three stages: (1) identify candidates — any student who ever appeared in the focal major; (2) classify outcomes — determine what happened to each candidate relative to the major; (3) filter and label — include the desired outcome groups and assign labels. The result (a tibble with student_id, population_label, outcome, entry_pathway, origin, entry_method, entry_status, relevant_until) is passed to every downstream analysis.

Outcomes

  • ongoing — still declared in the focal major in the most recent data term.
  • graduated — received a degree in the focal major in their last focal term.
  • switched_out — left the focal major but remained at UNM. Detected two ways: (1) a formal declaration of another major after their last focal term in cedar_programs; (2) any enrollment record in cedar_students after their last focal term, even without a re-declaration.
  • stopped_out — all declared candidates not accounted for by ongoing, graduated, or switched_out. No UNM enrollment or major record after their last focal term.
  • chose_elsewhere — appeared only as a pre-major; never declared the focal major, but did declare a different major afterward.
  • left_undeclared — appeared only as a pre-major; never declared any major and has no later major record in the available data. Displayed as Stopped before declaring.

Entry pathway (<code>entry_pathway</code>)

How the student arrived at the focal major — computed by get_entry_pathways() :

  • direct — first major at UNM was the focal major (no prior declared major or pre-major).
  • switched_in — had a non-focal declared major before declaring the focal major.
  • pre_major — appeared as a focal pre-major before (or instead of) declaring.

Entry classification columns

  • entry_method (classify_entry_method()) — first_program: no prior major record of any kind before this unit; switched_in: had at least one prior major record; unclear: first unit record is at the earliest available term, so prior history is unobservable.
  • entry_status (classify_entry_status()) — whether the student’s first record in this unit was as a pre_major or a declared major.

Enrollment window (<code>relevant_until</code>)

Each non-ongoing population student carries a relevant_until term: their last_declared_term (last term with a declared, non-pre-major focal record). Course enrollments after that term are excluded from all analyses. A student who was History for 2 terms, then switched to Business for 8 terms, contributes only the 2 History terms to the analysis. Ongoing students have relevant_until = NA (no restriction).

Worked example — dept = HIST, default scope (declared + pre-major)

student_id program_name program_type is_pre_major outcome result
S001 History Major FALSE ongoing ✓ included
S002 History Second Major FALSE ongoing ✓ included (Second Major counts)
S003 History Major TRUE chose_elsewhere / left_undeclared — excluded unless pre-major scope is included
S004 English Major FALSE — excluded (different dept)
S005 History Minor FALSE — excluded (Minor)

What programs belong to a department? The selector uses cedar_programs$dept_code, which is assigned during transformation from program/catalog and subject lookup tables with a final identity fallback when no explicit mapping exists. Mapping issues are surfaced under Admin → Data & Usage → Mappings; questionable fallbacks also appear in the Pathways scope bar.

2. Roadblocks — DFW as a Predictor of Leaving

File: R/cones/stopout.R
Functions: get_stopout(), classify_outcomes(), compute_stopout_for_group()

For each course, compares the fraction of group students who did not return the following term among those who got a DFW grade versus those who passed. The gap between those rates is the key signal.

Step 1: Classify outcomes (per student per course per term)

registration_status_code final_grade classified as
DG / DW (late drop) any dfw — this is the W in DFW; most withdrawals post as late-drop status rows
RE / RS / RR D, D+, D–, F, W, RD, RF dfw
RE / RS / RR A–C, CR, P, S, RA–RC, RCR pass
RE / RS / RR I, AUD, NR, or other excluded — ungraded, no signal
DR (early drop) any excluded — a drop before the deadline posts no grade; registration churn, not an academic outcome
WL / other any excluded

Step 2: Determine whether each student returned the following term

For each student in each term, we check whether they appear in cedar_students in the next fall or spring. Summer is not counted — skipping summer is normal and not a stop-out.

Graduate correction

Students who earned a degree in term T are not counted as stopped out for that term, even though they don’t appear in term T+1. Without this correction, every graduate who finished their program would be misclassified as a stop-out. The correction uses cedar_degrees$term to identify graduation terms.

⚠ Partial coverage: Graduate correction only applies to degrees recorded in CEDAR. Students who transferred out or completed credentials not in cedar_degrees will still appear as stop-outs.

Step 3: Compute rates and gap

student_id BIOL 2310 outcome returned next term?
S001 pass (A) yes
S002 pass (B) no
S003 dfw (F) yes
S004 dfw (W) no
S005 dfw (W) no

pass_stopout_rate = 1/2 = 0.500 (S002 didn’t return)
dfw_stopout_rate = 2/3 = 0.667 (S004, S005 didn’t return)
stopout_gap = 0.667 − 0.500 = 0.167
p_value: chi-squared test on the 2×2 contingency table (outcome × returned). Skipped if either group has fewer than 5 students — result is NA.

⚠ Known anomalies to watch for:
  • Observation window: analyses whose outcome lives in later terms (stop-out, course pairs, course-to-major entry) exclude records too recent to have a complete follow-up window — stop-out caps outcome terms one regular term before the last complete term, course pairs require the full max-gap window on the A side, and the course-to-major To term defaults to the same boundary. Without this, recent records would all read as non-returns / non-entries simply because the data ends.
  • Rows where pop_n_dfw is very small (1–4) produce unreliable rates. The Min group DFW students filter (default 5) removes these.
  • The baseline is ALL non-group students in the same courses.
  • Stop-out is measured as ‘returned to UNM,’ not ‘continued in the program.’

3. Course Timing — When Students Take Each Course

File: R/cones/pathway.R
Functions: get_course_timing(), plot_curriculum_map()

Computes where population students took each course along the selected x-axis. The default x-axis is total-credit bands, so transfer and continuing students are compared by credits earned rather than by calendar year or first observed term.

X-axis choices

  • Total credits: 0–30, 31–60, 61–90, 91–120, 121+ credits earned, including transfer credit.
  • UNM credits: the same bands, using institutional credits attempted only.
  • Relative term: 1st, 2nd, 3rd… observed enrolled term for each student.
  • Classification: Freshman, Sophomore, Junior, or Senior at the time of enrollment.

How relative term is defined

Relative term 1 is the first term in which the student has a registered course record in cedar_students. It is not necessarily their first semester at UNM or their first semester in the program. It is row_number() over distinct enrolled terms, sorted by UNM term code.

Skipped semesters

The counter only increments for terms with actual registered enrollment. Gaps are invisible. A student enrolled in Fall, absent in Spring, enrolled in Fall has relative terms 1 and 2 — not 1 and 3. There is no concept of “missed term 2” in this model.

Summer terms

By default, summer does not advance the counter. Summer courses are pinned to the relative term of the immediately preceding fall or spring. A student taking a summer course between their 2nd and 3rd fall/spring semesters has those summer courses recorded as relative term 2. The current Pathways UI does not expose an Include summer toggle, so the app always uses the default non-summer-advancing behavior.

Denominator

Each cell is a percentage: students who took the course at that x-axis position divided by students observed at that position. For relative term, that means students whose enrollment record reached that term. For credit bands and classification, it means students with any enrollment in that band or class.

⚠ Left-truncation artifact — Freshman-start filter is applied automatically:

Students who were already enrolled when CEDAR data begins (Fall 2018) have relative term 1 set to Fall 2018, regardless of how long they had actually been at UNM. A senior in Fall 2018 looks like a first-semester student, which makes the chart meaningless. This is called left truncation.

To reduce this artifact, the app automatically restricts the relative-term axis to students whose first observed registered term in CEDAR is classified as Freshman. This is a practical proxy for first-semester students, not independent proof of first-time-freshman status. You can override this by selecting a different Starting Classification in the filters.

This filter does not apply to the Classification, Inst. Credits, or Overall Credits x-axis modes — those use actual Banner values recorded at the time of enrollment and are unaffected by when the data window starts.

4. Course Pairs — Common Sequences

File: R/cones/pathway.R
Function: get_course_pairs()

Finds ordered pairs (A → B) where group students took Course A in one relative term and Course B in a later term, within a configurable term gap.

Exact computation

  1. Assign relative terms, then self-join enrolled records on student_id where relative_term_B > relative_term_A and relative_term_B − relative_term_A ≤ max_term_gap and course_A ≠ course_B.
  2. Count distinct students per (course_A, course_B) pair.
  3. pct_a_to_b = students who took both ÷ students who took A.
⚠ This is correlation, not causation. A high pct_a_to_b means students who took A commonly went on to take B. It does not mean A is a prerequisite for B or that taking A causes students to take B.

5. Course to Major — Course Associations Before/Into the Unit

Files: R/cones/gen-ed-conversion.R (course + instructor associations), R/cones/major-changes.R (entry heatmap), R/modules/pathways.R (focal subject/dept resolution and display)
Key functions: get_course_major_associations(), get_entry_heatmap()

This subtab has two related but different scopes. The Course + Instructor Associations table is department/course scoped: the selected Pathways population is used to resolve the focal department and subject prefixes, but the table itself is computed from all enrolled students in those focal courses. The Courses Before Major Entry heatmaps are population scoped: they use only students in the selected population and look backward from each student's first focal program record.

Course + Instructor Associations

  1. Resolve focal subject prefixes from the selected population's department codes. Department codes are not assumed to be course prefixes; they are translated through cedar_lookups$subject_lookup.
  2. Filter cedar_students to registered enrollments in those focal subjects. The level, campus, Gen Ed only, and date-range controls apply here.
  3. For each enrollment, find the student's first cedar_programs record in the focal department (program_type %in% c('Major', 'Second Major')). A student is eligible for that course term only if they had no department major or pre-major before or during the enrollment term.
  4. Later entered means the first focal-department program record appears after the course term. This includes students whose first focal record is a pre-major or a declared major.
  5. Rows are grouped by subject_course + course_title + instructor_name, so topics courses with the same number but different titles stay separate. Distinct students are counted within each group; totals across visible groups are group memberships, not unique headcount, because one student can take multiple focal courses.

Courses Before Major Entry heatmaps

  1. Use population$first_unit_term as each student's entry anchor. This is scoped to the focal program and avoids accidentally anchoring switchers to their prior non-focal major.
  2. Build lag terms by walking backward through the sorted non-summer term sequence. T-1 is the prior regular term, T-2 two regular terms back, and so on.
  3. Count population students who took each course at each lag. Split courses into focal subjects versus other departments.
  4. Compute pct_of_majors as students in that course-lag cell divided by the selected population size, and pct_converted as those students divided by all students enrolled in the same course/term slots. The heatmap currently visualizes pct_of_majors.
  5. The heatmaps use Min N and Heatmap lag only. Campus, level, Gen Ed only, and date-range controls are association-table filters and do not affect the heatmaps.
⚠ Interpretive boundary: Course to Major is descriptive. It can show which courses students commonly took before or near department entry, and which course/instructor groups are associated with later department records. It does not establish that a course or instructor caused a student to declare.

6. Major Changes

Files: R/cones/major-changes.R (detection and summarization), R/branches/population.R (group building), R/modules/pathways.R (focal program derivation and display)
Key functions: detect_major_changes(), mc_data()

Detects when a student’s primary declared major changed from one observed primary-major record to the next, then summarizes those transitions for the selected student group.

Banner/MyReports fields used by this tab

Major Changes uses normalized CEDAR tables, but the values come from specific Banner/MyReports fields. These derivations matter for interpretation:

  • cedar_students$term comes from class-list Academic Period Code. The movement cards use each student's minimum observed cedar_students$term as their first observed class-list enrollment. This is not a formal Banner matriculation/start-term field; it is the first term CEDAR sees that student in a class-list enrollment row.
  • cedar_student_term_credits is derived by CEDAR from cedar_students. It stores observed UNM credits by student_id and term, including cumulative attempted credits and cumulative completed credits from credit-earning grades. Movement card credit medians use this class-list-derived table, not Academic Studies UNM credit totals.
  • cedar_programs$term comes from academic-studies Academic Period, converted to a CEDAR term code.
  • cedar_programs$program_name, program_type, major_code, and program_code come from the academic-studies program columns such as Major, Second Major, Major Code, Second Major Code, and Program Code. CEDAR expands those wide Banner columns into one row per student-program-term.
  • cedar_programs$is_pre_major is computed by CEDAR from program naming/code patterns. A pre-major to full-major progression inside the same program is treated as a status progression, not a major-change event.
  • cedar_programs$student_population comes from academic-studies Student Population and is used to label students as Always UNM vs Transfer.
  • Credit positions do not come from the Banner cumulative fields. Institution Credits Attempted and Overall Credits Attempted are reported as of the moment the data was pulled and stamped onto every historical row, so a student's freshman record can read their final credit total. Measured across a full historical re-pull, they change from term to term only 16% of the time, and they overstate the position at a student's first term by a median of 84 credits. Every credit figure on this tab is instead built by build_credit_timeline() from observed class-list credits, plus a transfer block recovered as the gap between the two cumulative fields — a difference taken at one instant, so it survives the freeze. Transfer credit is attributed to the student's start, and students whose UNM history predates the data window are flagged rather than averaged in.

Step 1: Detect change events

Source: detect_major_changes() in R/cones/major-changes.R.

  1. Filter cedar_programs to program_type == “Major” rows for the population students only.
  2. Sort by student_id, term. Use lag() to get each student’s program in the prior term (prev_major) and their prior academic level (prev_level).
  3. Flag a change when program_name != prev_major AND (is.na(prev_level) | student_level == prev_level). The level check excludes transitions between undergraduate and graduate programs — a History BA student enrolling in Law School is not a “major change” in the undergraduate sense. First records are not change events because prev_major is missing.
  4. Each flagged row becomes one change event with: student_id, change_term, from_major, to_major, and the student’s credit position at the change — unm_credits_before_change (UNM only) and total_credits_before_change (UNM + transfer). Both are attempted hours, so they aren’t deflated by W/F grades from the abandoned major.
  5. Which term’s position? A major change typically posts to Banner the term after the student actually switches, so the figure reported is the position at the end of prev_term — how far along they were when they switched, not after the paperwork caught up.
  6. Where the credits come from. Not from the Banner cumulative columns: those are stamped as of the data pull onto every historical row, move across a student’s own terms only 16% of the time, and overstate a first-term position by a median of 84 credits. build_credit_timeline() builds the position from observed class-list credits plus a transfer block recovered as the gap between the two cumulative columns. Events whose student has UNM history predating the data window are flagged credits_position_valid = FALSE and excluded from credit averages — avg_credits_before_major() reports how many per major in n_excluded_position.

Worked example — History student program history

student_id term program_name student_level prev_major result
S001 202310 Psychology Undergraduate (none) — first term, no change
S001 202380 Psychology Undergraduate Psychology — same major
S001 202410 History Undergraduate Psychology ✓ change event: Psych → History
S001 202480 History Undergraduate History — same major
S001 202710 Juris Doctor Graduate/GASM History — level changed (UG→GR), excluded

Step 2: Derive focal majors

Source: mc_data reactive in R/modules/pathways.R.

Focal majors are the majors that define the selected student group — not all majors ever held by group members. A History population student who also declared Political Science should not make PolSci a focal major.

  • Dept mode (e.g., HIST): all majors where dept_code == “HIST” and program_type %in% c(“Major”, “Second Major”) in cedar_programs.
  • Specific majors mode: exactly the majors the user selected in the population filters.
  • Preset mode: the program_names list from the population opt.

Step 3: Filter to focal changes

From the full set of change events, keep only rows where from_major %in% focal_programs OR to_major %in% focal_programs. This means a History population sees:

  • Psychology → History (arriving to History) ✓
  • History → Political Science (leaving History) ✓
  • Political Science → Law (made by a History student, but neither side is History) ✗ excluded

Step 4: Build summary outputs

Source: mc_data() in R/modules/pathways.R, using change events from detect_major_changes().

  • Inflow / Outflow table: count change events by to_major (arrivals) and from_major (departures) in focal changes, then filter to rows where the major is in focal_programs. Net = arrivals − departures.
  • Common Pathways table: group focal changes by (from_major, to_major), count events, and compute median class-list-derived completed and attempted UNM credits through prev_term, the term before the change posted. Minimum threshold (default 3) removes rare pairs.
  • Trend sparkline: per-term count of arrivals (to_major %in% focal, green) and departures (from_major %in% focal, red).
  • Donuts: “Leaving for” = top to_major values among departures. “Arriving from” = top from_major values among arrivals. If the selected unit contains multiple focal majors, focal-to-focal changes can appear.

Step 5: Build major-status movement cards

The movement cards at the top of the tab are built separately from the legacy population entry columns. They use raw selected-unit program records from cedar_programs so each card has a clear event definition.

  • First pre-major declaration: first selected-unit program record where is_pre_major == TRUE, when it occurs before any full-major record for that selected unit.
  • Direct full-major declaration: first selected-unit full-major record when no earlier selected-unit pre-major record is observed.
  • Pre-major to full major: students with both a selected-unit pre-major record and a later selected-unit full-major record. Terms are counted from first selected-unit pre-major record to first selected-unit full-major record.
  • Left for another major: first focal-touching change event where from_major is selected-unit and to_major is outside the selected unit. Graduations are not included in this card.

Movement-card credits come from cedar_student_term_credits. The headline card value is median cumulative completed UNM credits through the event term; the detail table also shows cumulative attempted UNM credits from the same class-list source and transfer-inclusive attempted credits from Academic Studies.

Median terms uses term_diff(), which counts Spring/Fall steps only by default: Spring → Fall = 1, Fall → next Spring = 1, and summer is not counted as an additional term. Entry cards count from first observed class-list enrollment; conversion cards count from first selected-unit pre-major record; departure cards count from first selected-unit record.

Because first observed class-list enrollment is not a formal Banner start date, headline entry cards exclude records already present at the data-start term and records whose first selected-unit program record already has substantial class-list-derived attempted UNM credits. Those uncertain records remain visible in the movement detail table, but they are not summarized as new declarations. The Major Changes scope stripe reports these excluded entry students explicitly.

Worked example — Inflow / Outflow for a History department population

major students arriving to students leaving for elsewhere net
History 47 31 +16
History / Pre-Law 5 12 −7

Only History-dept programs appear. The 47 arriving students came from other majors; the 31 departures went to other majors (shown in the “Leaving for” donut).

⚠ Known edge cases:
  • A student who switched History → PolSci → History generates two change events. Both appear in the tables. The net can mask churn.
  • Pre-major → declared transitions within the same program are not flagged as changes (same program_name, different is_pre_major flag).
  • The minimum event threshold filter removes pairs with fewer than N events. Rare pathways that may still be meaningful are hidden. Lower the threshold to see them.
Reading this with Claude or GitHub Copilot:

Each section above names the exact file and function that implements it. To go deeper, open the file in your editor, select the function body, and ask “explain this function” or “what does this do step by step?” All functions have parameter descriptions in the header comment.

For a fuller picture, paste the function into Claude along with a specific question — for example: “Why does get_switched_out_ids() use last_focal_term + 100 as an upper bound?” or “What edge cases does the enrollment-based switch detection handle that the program-record check misses?” The code is designed to be readable; the AI fills in the reasoning.

Methodology reflects: R/branches/population.R (group builder), R/cones/stopout.R, R/cones/pathway.R, R/cones/major-changes.R, and R/modules/pathways.R (display logic). Update this panel when cone logic changes.

Course Dynamics

Enrollment trends, student flows, grade distributions, and outcomes for a single course.

Select a course, then click Analyze Course.

Course Overview

A same-season view of enrollment history, registration activity, active sections, and average section size. Campuses remain separate so differences between Main, Online, and branch offerings stay visible.

Enrollment History

Census and current enrollment for the selected term type. Solid lines show census enrollment; dashed lines show current enrollment. How enrollment is counted →

Active Sections

The number of active home sections in each same-season term.

Average Section Size

Crosslist-aware total enrollment divided by active home sections.

Enrollment

Distinct students on the class list for this course, by term. Current enrollment is students still registered when the data was pulled; census enrollment adds back late drops, who were present after census but left before the final class list.

More On How This Is Counted Current enrollment, census enrollment, and drop buckets.
  • Current enrollment counts distinct students with registered status codes RE, RS, or RR when the data was pulled.
  • Census enrollment is current enrollment plus late drops (DG/DW), because late drops were enrolled past census.
  • Early drops are DR/DD rows before grade consequence; they are shown separately and not included in census or current enrollment.
  • Late drops are DG/DW rows after the drop deadline; they are the gap between census and current enrollment.
  • Students are deduplicated within a course, campus, and term before status counts are summarized.
Full methodology →

Census vs Current Enrollment

Compares the current class-list count with census enrollment, which adds late drops back in. The gap shows how many students remained past census but were no longer registered when the data was pulled.

Early and Late Drops

Separates pre-census drops from late drops. Early drops show registration churn; late drops show students who stayed past census but were no longer in current enrollment.


Classlist Enrollment History

Reference rows for the plotted counts, including same-term-type historical averages and the drop buckets used to distinguish pressure from survival.

Course Flows

What you are looking at. Each diagram traces the courses students actually took around this one: what they took the term before (left), what they took the term after (right), and what they took alongside it. Band thickness is the average number of students per term who followed that path — so a thick band is a well-worn route, not a single unusual term. There is one diagram per term type, because fall and spring pathways often differ.

What it cannot tell you. These are observed patterns, not requirements and not causes. A heavy band may be a prerequisite, a scheduling convenience, or coincidence, and the diagram cannot distinguish them. It also is not one group of students followed all the way through — each band is counted separately, so you cannot read a single cohort across the whole picture. Paths below your minimum are hidden, so this shows the main routes rather than every route.

When it is useful. Seeing which courses reliably feed yours, or which yours feeds, helps with timetabling and seat planning — if forty students a term move from your course to the next one, that is next term's demand. It also shows whether a catalog prerequisite matches what students actually do, and surfaces informal pathways students have built that the curriculum does not name. If your course is a broad elective with no sequence, expect a diffuse picture — that is a finding too.

Full methodology →

Rollcall

Shows the student mix in this course by classification and major, split by term type and trended over time. Counts are based on distinct registered class-list students.

By Student Classification

Top 5 classifications plus Other, so each donut sums to 100%. Shares are of average total enrollment for that term type.

Fall terms
Spring terms

By Major

Top 5 majors plus Other. The full major list is in the table below.

Fall terms
Spring terms

Classification Trends Over Time

Major Trends Over Time

All Majors by Term

Every major in this course, as a share of enrollment each term — the full list behind the top-5 donuts above.

Registration Statistics

Flags courses where enrollment pressure is concentrated — sections filling faster than usual, growing waitlists, or drop rates above a course's own historical average. All comparisons are term-type matched and use historical-only means.

Open Seats

Courses with available capacity matching your filters, with DFW history and year-over-year schedule comparisons.

Waitlists

Students waiting for enrollment in full courses, by count, major, and classification. Waitlist status is a live registration state, so it is only meaningfully populated for the current term — past terms retain only the few students still waitlisted when the term closed. A nearly empty result for an earlier term means the data was not retained, not that there was no demand.

Minimum waitlisted
hides smaller rows in all three tables

Enrollment

Section-level enrollment from the Department Enrollment Status Report, with crosslist deduplication and historical comparison.

DESR

Section-level rows from the Department Enrollment Status Report — one row per scheduled section. Sect Enrl is that section's own registered count; Total Enrl combines the crosslist group, so it is the figure to use when adding courses up. The tabs below choose which side of a crosslist you see; start on Home, which counts each course once.

Your department's home/primary sections, plus all non-crosslisted courses. Each crosslisted course appears once, under its administrative home department.

Sections crosslisted across the undergraduate/graduate divide — at least one section at or below 499 paired with one at 500 or above. Each group appears once (home section shown).

Your department's sections that also appear under another department's course number — your course is home, theirs is the partner.

Sections owned by another department but crosslisted under your department's course number. Your number is the partner; the other department is home.

Every section including all crosslist partner rows. Crosslisted courses appear multiple times — once per subject code.

Classlist

The same scope counted from student records rather than section records. Each student is counted once per course, so crosslisted sections do not double-count. Use this when you want people; use DESR when you want scheduled sections — the two will not match exactly, and that gap is usually crosslisting.

Low Enrollment

Sections running under the review thresholds, split by course level because the bar differs for each. Set the thresholds below to match your own review rule. For current and past terms this reports what enrollment actually was; for a future term there is no enrollment yet, so it compares the schedule against each course's own history and flags what looks at risk — the banner tells you which mode you are in.

Thresholds:
How to read this table

Current / past terms (alerts mode):

  • Sects — number of active home sections of this course in the selected term.
  • Enrolled — this section's own registered student count.
  • XL Total — for crosslisted sections, the combined count across all partner sections; equals Enrolled for non-crosslisted courses.
  • Course Total — sum of XL Total across all home sections of this course. Color-coded against the threshold.

Future terms (concerns mode):

  • Sects — number of scheduled home sections.
  • Sect Enrl — current registration count for those sections.
  • Hist Avg — average combined enrollment over the last 4 same-type terms. Color-coded against the threshold.
  • Trend — ↑ up / ↓ down / ↔ stable based on linear regression slope across prior terms.
  • # Terms — how many prior terms contributed to the average.

Color bands: red = below 50% of threshold; yellow = 50–75%; blue = 75–100%; green = meets or exceeds threshold.

Full methodology →



Crosslisted courses that span the undergraduate/graduate boundary (at least one section ≤499 and one ≥500). The Sections column shows all partner courses in the group. Enrollment is the combined total.


Trend Explorer

Which courses in your current filters are growing or shrinking. Trends fit a straight line through each course's last six offerings, so a course needs at least two offerings to appear and a single unusual term can tilt a short series. Treat the lists as a shortlist to look into, not a ranking. For curated chair-facing patterns, use Dept Trends > Enrollment.

Enrollment by Campus and Level

Total enrollment broken out by campus and course level across your selected filters and terms.


A filter-driven workspace for exploring course enrollment trajectories. For curated chair-facing patterns, use Dept Trends > Enrollment. Based on linear regression across each course's last 6 offerings; courses with fewer than 2 offerings are excluded.

↑ Top Growing Courses
↓ Top Declining Courses

Headcount

Unduplicated students with an active declared program per term, drawn from Banner academic studies records.

Gen Ed

Aggregate view of Gen Ed enrollment and grade outcomes.

Gen Ed Overview

The comparative view of Gen Ed: how one department's courses stack up against Gen Ed as a whole, and how peer departments compare with each other. Select departments to get a labelled card row for each, measured against the overall benchmark. For one department's own Gen Ed detail, use Dept Trends > Gen Ed.

Who Takes Gen Ed, and How

Delivery mode and the mix of majors sitting in Gen Ed courses across the selected terms.

Enrollment by Modality

Face-to-face versus online enrollment each term.

Major Mix in Gen Ed Courses

Which majors the Gen Ed seats are serving.

Top Gen Ed Enrollment by Course and Campus

The highest-enrolling Gen Ed courses, with delivery campuses kept distinct.

Department Summary

Gen Ed teaching load by department: how many courses each offers and how much enrollment it carries.

DFW Rates by Course

Grade outcomes for each Gen Ed course, split by campus. DFW % counts non-passing grades plus late withdrawals (W) as a share of graded attempts, and equals Below C % + W % — the two are computed separately from their own counts, so they are a check on each other.

Early drops are not part of DFW. Students who dropped before the grade deadline are excluded from both the numerator and the denominator. Early Drop % is shown for context and uses a different base (attempts plus early drops), so it does not add into the other columns.

Grade Distribution

Full grade spread across the selected Gen Ed courses, split by campus so rows line up with the DFW table above.

Cancellations

Cancelled sections matching your filters, with timing shown relative to course start.

Data Status & Usage Analytics

Data presented here is MyReports data — not official institutional data — and should not be used for required reporting purposes. CEDAR tables are updated nightly for the current semester and +/- 1-2 terms.


Last updated information for all loaded datasets. This data is computed at startup.


Department, subject, and program mappings used by Cedar at startup. Mapping issues are surfaced here so unusual Banner codes can be reviewed without blocking the app.

Mapping Issues

Rows listed here are excluded from lookup vectors until they are mapped or explicitly reviewed. They may still appear in source data.


Validated major/program code to department-code lookup used for home-major classification and transform fallbacks.


Course subject prefixes mapped to Cedar department codes. Use this when interpreting course ownership.


Department code display names derived from the subject/dept catalog.


Program codes intentionally allowed to remain unmapped at app startup. These should be treated as a review queue, not permanent truth.




Usage Dashboard
Top Tabs
Report Types
Departments Viewed
Courses Viewed
Campus Scope
Daily Activity



Usage Event Log

Course Dynamics Cache

CEDAR caches expensive lookup calculations, including course-flow analysis, to speed up repeated Course Dynamics requests. The cache automatically invalidates when data changes.


Department Trends Cache

Dept Trends headcount/base payloads are cached to disk by department and ISO week. Longer-running trend tabs still compute lazily when opened.

Dept Dashboard Cache

Dept Dashboard snapshots are cached by department, campus scope, selected term, date, and CEDAR table hashes. Production data refreshes warm the primary audience dashboards each morning.

Pathways Population Benchmarks

College comparison benchmarks in the Pathways Population tab are cached by CEDAR current term, college, campus, student level, and population scope. Clear this after changing the benchmark logic or when a mid-semester data correction should be reflected immediately.

Report Timing Estimates

CEDAR learns separate calculation and cache-hit estimates from completed report runs. It also measures the additional time until the browser is usable and estimates the output payload size. Post-compute time includes serialization, transfer, and browser rendering.


Payload size is an approximation based on values delivered to Shiny outputs; it is not a network-byte counter.

CEDAR Changelog

Recent Updates
All Changes