Tidy Data (Sep 8) — Session Notes

Notes for the Tidy Data session, Tuesday September 8, 2026, 9:00 am to 12:00 pm Pacific, online. Based on Library Carpentry’s Spreadsheets / Tidy Data for Librarians lesson, taught in Google Sheets.

The first part of this page is a reference you can use during and after the session. The run sheet and instructor guide further down are open for anyone who wants to see how the session is put together or teach it themselves.


The practice data

training_attendance_practice.xlsx is a teaching build derived from the Library Carpentry training_attendance.xlsx (fictional records of library training sessions, 2015–2017). It is published as a Google Sheet; the “practice sheet” link above prompts you to save your own copy, which you edit for the whole session. Tabs:


The one rule

A rectangular table processes the same way on every row:

Everything in this session is a version of this rule. Some layouts are built to be read at a glance (titles, colour, spacing). A rectangular table is built to be processed. You can always build a nice view from the table; you cannot reliably process the pretty layout.


Google Sheets: where things live

Task Path
Duplicate a tab right-click the tab → Duplicate
Delete rows select the row numbers → right-click → Delete rows
Unmerge cells Format → Merge cells → Unmerge
Number / date format Format → Number
Data validation Data → Data validation → Add rule; Advanced options → If the data is invalidReject the input
Sort a table Data → Sort range → Advanced range sorting options; tick Data has header row, then sort
Conditional formatting Format → Conditional formatting → Color scale tab
Version history File → Version history → See version history
Download as CSV File → Download → Comma-separated values (.csv) (current sheet only; one download per tab)
Locale File → Settings → Locale

Functions we use

Function What it does
=ISNUMBER(A2) TRUE if the cell holds a real date value, FALSE if it is text
=ISTEXT(A2) the mirror check: TRUE if the cell is text
=YEAR(A2) pulls the year out of a real date
=MONTH(A2) pulls the month (1–12)
=DAY(A2) pulls the day of the month

ISNUMBER returning TRUE means the cell holds a real date, not that the date is correct.


Missing values


Dates

A date in a spreadsheet is in one of three states, and all three can look identical in the cell:

  1. a recognised date value — stored as a number, shown through a display format
  2. text that happens to look like a date
  3. a recognised date with the wrong value in it

Locale (File → Settings → Locale) sets the default date format and how Sheets reads ambiguous date text (03/04/2016 as March 4 or April 3). Once Sheets has stored a real date, changing locale changes how it is written on screen, not which day it is.

The defensive move


Export to CSV


AI tools and your data


Self-check questions

  1. Look at 2016_messy. Name one thing a program would choke on.
  2. In a tidy table, the months of the year should be: (a) twelve columns Jan–Dec, (b) one column called month, (c) colour-coded rows. (Answer: b)
  3. Turn the RDM table in 2016_messy into a tidy table: one table, header in row 1, one value per cell (split PGR|PDRA|other), a real cancelled column, consistent nulls. Write down your data row count.
  4. In 2017_messy, run =ISNUMBER() down the RDM Date column. Which rows come back FALSE (stored as text)? Then in dates, add year with =YEAR(). Which two rows have the wrong year? (the events were in 2015)
  5. True or false: if a cell shows 2016-03-04, the file definitely stores March 4 2016. (Answer: false — it could be text, or a real date with a wrong value)
  6. Sort the whole dates table by len_hours, largest to smallest. What junk shows up at each end?
  7. You sort a table to find outliers. What two things do you do first? (Answer: select the whole table; tick Data has header row)
  8. An AI hands you a clean-looking table. First thing you do before you use it? (Answer: compare row count and values against the raw data)

Resources


Run sheet

180 minutes. First keyboard action at minute 8; a curated slice of the data rather than a full year; a real 10-minute buffer at the end.

Time Min Segment What happens
0:00 12 Welcome + first hands-on Norms. Everyone makes their copy, duplicates the 2016_messy tab to 2016_clean, deletes the title/spacer rows. One real edit before minute 10.
0:12 16 Why + tidy data Name the two things they just did: work in a copy; a rectangular table processes consistently. The rule. One value per column. Think-pair-share on 2016_messy.
0:28 25 Formatting problems (the core) Demo on the RDM table: unmerge the title, split the packed PGR\|PDRA\|other cell into three columns, recode grey-shaded cancelled rows into a cancelled column. Learners take the Open-access table (units in Len, name drift) against checkpoint_clean. Flag the two 1900 dates.
0:53 8 Break  
1:01 4 Combine Show checkpoint_combined: 2017 rows cleaned the same way, plus a year column. Row-count check: 2016 + 2017 = combined − 1 header. 7/8 Feb is a judgement call, not a cleanup.
1:05 25 Dates as data Three states: real value / text / real-but-wrong. Format → Number to show value vs display. Locale = display and text parsing, not the stored day. =ISNUMBER on 2017_messy catches the text dates. =YEAR on dates catches the 2017→2015 bug (and the 1900s in 2016_messy).
1:30 25 Quality control QA: Data → Data validation, a number range and a dropdown, “Reject the input”. QC: sort the whole table with Data has header row ticked; Format → Conditional formatting → Color scale. Zeros are a question for the data dictionary, not an auto-blank.
1:55 8 Break  
2:03 22 Export Why CSV. File → Download → CSV = current sheet only. Date gotcha: CSV keeps the displayed string, so format with the full year first. Comma quoting. CSV drops your change log.
2:25 15 AI as a downstream consumer Data caution. A saved genuine flawed AI output plus a source_row_id audit. Optional live rerun. AI shifts work to specifying and verifying; it still does not count reliably.
2:40 10 Wrap Recap the five concepts. Change-log habit. Resources. Feedback.
2:50 10 Buffer Catch-up, questions, or an early break.

Instructor guide

Should you teach the lesson as-is?

Teach it, but reframe it. The lesson was written around Excel in 2016 and it shows in places (1900 vs 1904 date systems, CR/LF line endings, “which application should I install”). Little of that matters to a general library audience. What the lesson gets right has only become more important: data structure literacy. Columns are variables, rows are observations, one value per cell, raw data left untouched, dates are dangerous, export to open formats.

Since 2016, fewer people need to hand-clean a spreadsheet. Google Sheets autoformats, has version history, and now has Gemini in the sidebar. Excel has Copilot. ChatGPT and Claude will reshape a table on request. So the mechanical skills in the lesson are increasingly things a tool does for you. That makes the lesson a supervision skill: to get usable output from an AI tool or a research assistant, you have to know what tidy data looks like and be able to check whether what came back is correct.

What is timeless

Adapting the Excel lesson for Google Sheets

Lesson content (Excel) Google Sheets
“Install LibreOffice or Excel” Skip. Everyone has a browser.
1900 / 1904 date systems Not a thing in Sheets. Sheets is locale-sensitive instead: File → Settings → Locale sets the default date format and how ambiguous date text is read. It does not change which day an already-recognised date is.
“Save As CSV loses my dates” In Sheets, CSV export writes the displayed date string. 4 Mar exports with no year; 2016-03-04 keeps it. Fix: format with the full year before export.
ISDATE() to test date-vs-text Do not use it: ISDATE("July 20 1969") returns TRUE, so parseable text passes. Use =ISNUMBER() / =ISTEXT().
CR/LF line endings Cut it. Not actionable for this audience.
Raw-data preservation Version history helps, but teach the discipline: source file read-only, work in a named copy. Duplicating a tab keeps both in the same file, so it is a working copy, not a backup.

Pedagogical approach

Concept budget

Five core concepts, three practices, one framing idea. Do not add a sixth core concept mid-session.

Prep

The AI segment

Do not rely on a live model failing in an instructive way. Run “Clean this up and make it tidy” on the ai_input tab before class (12 rows, source_row_id 1–12; rows 5, 7, 11 have a blank num_attended), save an output that dropped a row or mangled a value, and use that as the audit exercise. In class: show the saved output next to ai_input, state the row counts, and have learners find the missing row by comparing source_row_id values. Then ask how they would catch it without the row IDs (row counts before and after; compare to the raw data). Optional live rerun to show output varies.

Takeaway: AI may shift work toward specifying and verifying transformations. It does not remove the need to inspect and clean, and it does not count reliably.


This page and the practice materials are shared under CC BY 4.0. The underlying lesson is Library Carpentry’s, also CC BY 4.0.