Skip to content

2 · Clean and join with an agent

Clean two messy tables with an agent, join them on a shared key, then produce a verification note documenting every decision. This is Stage 2 of your capstone workflow.

Time ~65 minutes, in class
Work with A partner (or your capstone team)
You need An agent (Claude or Manus) + a spreadsheet
You hand in A cleaned, joined CSV + a one-page verification note
Graded on Specificity, logic, verification — not speed

Kopi Kembali runs a loyalty programme. Marketing wants to know how much loyalty members spend — which means joining two exports:

  • kk-customers.csv — the loyalty member list (~300 members, 303 rows)
  • kk-orders.csv — 1,204 order rows, January to August 2026

Data dictionaries

kk-customers.csv kk-orders.csv
customer_id order_id
name customer_id
join_date order_date
tier (Bronze, Silver, Gold) outlet
home_outlet amount_sgd
marketing_opt_in

Do not use the agent yet. Open both files in a spreadsheet and answer for yourself:

  • Customers: How many rows? Any missing values, and in which columns? What date format? Any inconsistent category spellings in tier? Any duplicate customer_id?
  • Orders: How many rows? Any missing values or duplicate order_id? Date format? Do all customer_id values appear in the customers table?

Then decide your join and write it down before you run anything:

  • Which column will you join on, and why?
  • Inner join (keep only matched rows) or left join (keep all customers)? Why?
  • Roughly how many rows do you expect in the result? Which rows do you expect to be dropped?

Prompt 1 — profile only (do not clean yet):

I have two CSV files: kk-customers.csv and kk-orders.csv.
Before I ask you to clean them, profile them. For each table tell me:
1. The number of rows
2. Every column name and its data type
3. The number of missing values in each column (counts, not percentages)
4. Any obvious quality issues: inconsistent formatting, outliers, duplicates
(for customers, count duplicate customer_id; for orders, count duplicate
order_id), or pre-calculated columns
Do not clean anything yet. Just profile and report.

Prompt 2 — execute your plan. Replace [YOUR PLAN] with the plan you wrote in Part 1:

Based on your profile, here is exactly what I want you to do:
[YOUR PLAN]
As you work:
1. Show me the row count before and after each step.
2. For missing values: tell me which column, how many, and exactly what you did.
3. For duplicates: show which rows were duplicates and why you removed them.
4. For any standardised format (dates, categories): show the mapping you used.
5. For the join: tell me which column(s) you joined on, how many rows from each
table matched, and how many rows were dropped and why.
Then return the cleaned and joined dataset as CSV.

Watch it work and note: Did it ask clarifying questions? Did it show row counts for each step? Did anything surprise you or differ from your plan?

Save the output as cleaned_joined.csv and screenshot the transcript.

This note is your portfolio deliverable. One sentence per decision. Specific, not vague. Fill in the template:

VERIFICATION NOTE
Team: ______ Date: ______
Dataset: Customers and Orders (joined on customer_id)
ROW COUNTS
Customers, starting: ___ Orders, starting: ___
Customers, cleaned: ___ Orders, cleaned: ___
Final joined result: ___
CLEANING DECISIONS (customers, then orders)
Missing values — which column, how many, how handled, why defensible
Categories — which column, what was inconsistent, mapping, how verified
Duplicates — how many, true dupes or legit records, what you did
Dates — standardised to YYYY-MM-DD? how many had issues
THE JOIN
Join key + why · join type (inner/left) · matched rows ·
rows dropped from each table · one-sentence reason the drop is acceptable
DISTRIBUTION CHECK (for any numeric column the agent modified)
before vs after: mean, median, range — substantially different? why acceptable?
SUMMARY (one sentence): what this dataset now contains and what was cleaned.
  1. Open cleaned_joined.csv and pick one row.
  2. Find its customer_id in the original customers table — does the name match your joined row?
  3. Find its order_id in the original orders table — does the amount match?
  4. In a categorical column, eyeball a few values — are they plausible, or did the agent invent categories to fill blanks?

If either trace does not match, you may have a join problem — flag it.

  • cleaned_joined.csv — one observation per row, one variable per column, one value per cell
  • Column names consistent (lower_case_with_underscores); dates all YYYY-MM-DD; numbers stored as numbers
  • Verification note names each cleaning action with a defensible reason
  • The join section states matched rows, dropped rows, and why the drop is acceptable
  • At least one row traced by hand, end to end
  • Distribution check done for any numeric column the agent modified

Save both artefacts in the team Drive workspace and link them from your individual portfolio. Each member also submits the Stage 2 xSiTe checkpoint record, linking the exact Sheet tab and Project Hub row and stating their personal contribution.

Your team does this same work on your chosen scenario dataset in Stage 2 (Wrangle). Fill in the Stage 2 row of your orchestration log with: what you asked the agent, what it produced, what you accepted/changed/rejected and why, and how you verified it. Do it during your team meeting, not from memory at the end — the log is where supervision lives. See the Orchestration Log Template (Assessment Pack folder in Google Drive) for the template and a worked example.