Practice Datasets
Reading about a t-test is not the same as running one. These eight small, realistic CSV files each come with a story, three suggested exercises, and a worked solution with the real numbers, so you can practice every analysis on data that behaves like the messy, interesting real thing.
How to use them: download a CSV, open it in SPSS, JASP, R, Python, or even the Descriptives calculator right here, and try the exercises. Peek at the worked solution only after you've had a go. The numbers there are computed from the exact file you downloaded, so they'll match if you did it right.
Every file is generated by a seeded, committed script (tools/make-datasets.py, master seed 20260709). Rerunning it reproduces byte-for-byte identical CSVs, so the shipped worked-solution numbers stay true. Nothing here is uploaded anywhere; the files are static.
- 😴 Sleep & attention
two-group t-test · 80 rows - 📚 Study methods
one-way ANOVA · 105 rows - 📱 Screen time & sleep
correlation + outlier · 60 rows - 🧠 Memory 2×2
factorial ANOVA · 100 rows - 🙂 Wellbeing survey
Likert · reliability · 120 rows - 🩺 Messy clinic intake
data cleaning · 52 rows - 🏋️ Strength training
wide · repeated measures · 60 rows - 🎓 Grad admissions
logistic regression · 160 rows
😴Sleep & attention
⬇ sleep-experiment.csv · 80 rowsEighty volunteers were randomly assigned to a normal night's sleep or a night restricted to four hours, then took a 30-minute vigilance task the next morning. The outcome is the number of attention lapses (errors). Did sleep restriction hurt performance, and by how much?
| Variable | Type | Description |
|---|---|---|
| participant_id | ID | 1–80, one row per person |
| condition | categorical | normal_sleep vs restricted_sleep (40 each) |
| errors | count | attention lapses on the vigilance task |
Try these
- Run an independent-samples t-test comparing errors across the two conditions.
- Report and interpret Cohen's d: the study was built around a medium effect (check it with the effect-size converter).
- Before trusting the p-value, check the assumptions (normality, equal variances).
Worked solution: the key numbers
normal_sleep: M = 20.07, SD = 5.92, n = 40restricted_sleep: M = 22.77, SD = 6.02, n = 40- Independent t-test: t(78) = 2.02, p = .047
- Effect size: d = 0.45, a medium effect. Restricted sleepers made more errors.
📚Study methods
⬇ study-methods.csv · 105 rowsThree groups of 35 students revised for the same exam using one of three techniques (rereading, flashcards, or practice testing), then sat the exam (scored 0–100). Which method wins? And notice the spread differs by group, so this doubles as a homogeneity-of-variance workout.
| Variable | Type | Description |
|---|---|---|
| student_id | ID | 1–105, one row per student |
| method | categorical | rereading · flashcards · practice_testing |
| exam_score | continuous | final exam mark, 0–100 |
Try these
- Run a one-way ANOVA across the three methods.
- Check equal variances (Levene's test). The SDs are deliberately unequal.
- Follow up with post-hoc tests (e.g. Tukey) to see which methods actually differ.
Worked solution: the key numbers
- rereading: M = 66.14, SD = 7.97 · flashcards: M = 74.43, SD = 8.86 · practice_testing: M = 76.83, SD = 11.97
- SD ratio (largest / smallest) = 1.50, enough heterogeneity for Levene to notice.
- One-way ANOVA: F(2, 102) = 11.57, p < .001, η² = .185.
- Practice testing > flashcards > rereading; post-hoc, rereading is the one that clearly trails.
📱Screen time & sleep
⬇ screen-time.csv · 60 rowsSixty people reported their average daily screen time and rated their sleep quality (0–10). There's a real negative relationship in here, but one person (row 60) reports 11.5 hours of screen time and excellent sleep, sitting far off to the right. This dataset is really about what one influential point can do.
| Variable | Type | Description |
|---|---|---|
| person_id | ID | 1–60, one row per person |
| screen_hours | continuous | average screen time per day (hours) |
| sleep_quality | continuous | self-rated sleep quality, 0–10 |
Try these
- Plot it, then compute Pearson's r. Always look before you trust a coefficient.
- Fit a simple regression and inspect leverage & influence (Cook's distance) for row 60.
- Recompute r without that point, then decide what to do with it, and report both.
Worked solution: the key numbers
- All 60 points: r = −.21 (slope = −0.23), which looks weak.
- Drop the influential person 60 (11.5 h, 8.6): r = −.40 (slope = −0.56) — the real, moderate relationship.
- A single high-leverage point moved r by .19 and nearly halved the slope.
- Honest line (without the point): sleep ≈ 7.92 − 0.56 × screen_hours.
🧠Memory 2×2
⬇ memory-2x2.csv · 100 rowsA classic 2×2 memory experiment: participants encoded a word list either shallowly or deeply, then were tested in the same room or a different one (25 per cell). The number of words recalled hides a genuine interaction: context only matters when encoding was deep.
| Variable | Type | Description |
|---|---|---|
| id | ID | 1–100, one row per participant |
| encoding | categorical | shallow vs deep |
| context | categorical | same vs different room at test |
| recall | count | words recalled (0–30) |
Try these
- Run a two-way factorial ANOVA. You want the encoding × context interaction.
- Draw the interaction plot of the four cell means (non-parallel lines = interaction).
- Put the interaction into words: the effect of context depends on encoding depth.
Worked solution: the key numbers
- Cell means: shallow/same = 9.32, shallow/different = 8.20; deep/same = 19.04, deep/different = 14.12.
- Context effect when shallow = 1.12 words; when deep = 4.92 words.
- Interaction (difference of those differences) ≈ 3.80 words, so the lines are clearly non-parallel.
- Main effect of encoding is large; context alone is small — the story lives in the interaction.
🙂Wellbeing survey
⬇ wellbeing-survey.csv · 120 rowsAn 8-item wellbeing questionnaire (each item 1–5). Two items are negatively worded and must be reverse-coded before scoring: q3 and q6. A few cells are blank (real surveys have missing data). Practice reverse-coding, building a composite, and checking the scale's reliability.
| Variable | Type | Description |
|---|---|---|
| respondent_id | ID | 1–120, one row per respondent |
| q1 … q8 | ordinal (Likert) | 1–5 agreement; q3 & q6 reverse-worded; blank = missing |
Try these
- Reverse-code
q3andq6(new = 6 − old), then compute a composite (mean of the 8 items). - Assess the scale with Cronbach's α.
- Decide how to handle the missing values (listwise vs pairwise) and note how many cases each keeps.
Worked solution: the key numbers
- Reverse-code
q3andq6as 6 − x before anything else, or α will look terrible. - 51 cells are missing; listwise deletion leaves 75 of 120 complete cases (a real cost: pairwise keeps more).
- Cronbach's α (raw, complete cases) = .90, a reliable scale.
- Composite score: M = 2.88, SD = 0.93.
🩺Messy clinic intake
⬇ messy-clinic.csv · 52 rowsA deliberately dirty clinic intake sheet, built for the Data course. It hides duplicates, impossible values, a unit mix-up, inconsistent category spellings, and three different date formats. Your job is to find every problem before you analyze anything, and to never edit the raw file, only a cleaning script.
| Variable | Type | Description |
|---|---|---|
| patient_id | ID | P001–P050 (with two duplicated rows) |
| age | count | years (one value is impossible) |
| sex | categorical | eight different spellings of two categories |
| height_cm | continuous | cm (one row is in meters, another impossible) |
| weight_kg | continuous | kg (one is negative) |
| systolic_bp | count | mmHg (one is zero) |
| visit_date | date | three inconsistent formats |
Try these
- Find and document every data-quality problem. How many can you spot before reading the solution?
- Build a reproducible cleaning workflow: de-duplicate, standardize
sex, fix the units, parse the dates. - Write the validation rules (allowed ranges, allowed categories) that would have caught each error at entry.
Worked solution: the planted problems
- Duplicates: P004 is an exact duplicate row; P016 appears twice with a slightly different weight (near-duplicate).
- Impossible values: age 511 (P007, a typo for 51), systolic_bp 0 (P020), weight −78 kg (P031, a sign error), height 400 cm (P042).
- Unit mix-up: P013's height is 1.72 — that's meters, not cm.
- Inconsistent categories:
sexis spelled eight ways:Male/M/male/MalevsFemale/F/female/f/female(mind the whitespace). - Date formats: mostly ISO (
2025-06-08), but07/04/2025(P034) andApril 12 2025(P039) sneak in. - After cleaning: 50 unique patients remain (two duplicate rows removed); the impossible values are then fixed or flagged, not silently deleted.
🏋️Strength training
⬇ training-longitudinal.csv · 60 rowsSixty athletes were measured on a strength lift (1RM, kg) at weeks 0, 6, and 12, split between a training program and a control group. The data is in wide format (one row per athlete, one column per timepoint), perfect for practicing reshaping and repeated-measures analysis.
| Variable | Type | Description |
|---|---|---|
| athlete_id | ID | 1–60, one row per athlete |
| group | categorical | program vs control (30 each) |
| strength_wk0 | continuous | baseline 1RM (kg) |
| strength_wk6 | continuous | 1RM at week 6 (kg) |
| strength_wk12 | continuous | 1RM at week 12 (kg) |
Try these
- Pivot wide → long so each row is one athlete-at-one-time (R/JASP usually want long).
- Run a repeated-measures / mixed ANOVA with time (within) and group (between).
- Interpret the group × time interaction: does the program gain more than the control?
Worked solution: the key numbers
- Program means (wk0 / wk6 / wk12): 101.5 / 107.7 / 110.2 kg, a gain of about +8.7 kg.
- Control means (wk0 / wk6 / wk12): 101.9 / 103.8 / 105.1 kg, a gain of about +3.2 kg.
- Both improve over time, but the program improves more → a group × time interaction.
- After pivoting, you'll have 180 rows (60 athletes × 3 timepoints).
🎓Grad admissions
⬇ admissions.csv · 160 rowsRecords for 160 graduate applicants: undergraduate GPA, a GRE-style test score, whether they had research experience, and the binary outcome: admitted or not. A binary outcome means logistic regression, not linear.
| Variable | Type | Description |
|---|---|---|
| applicant_id | ID | A001–A160, one row per applicant |
| gpa | continuous | undergraduate GPA, 2.0–4.0 |
| gre_score | count | standardized test score (~260–340) |
| research | binary | 1 = has research experience, 0 = none |
| admitted | binary | 1 = admitted, 0 = rejected (the outcome) |
Try these
- Fit a logistic regression:
admitted ~ gpa + gre_score + research. - Interpret the odds ratios (convert them from the coefficients; the effect-size tool handles OR too).
- As a warm-up, compare admit rates by research with a chi-square test on the 2×2 table.
Worked solution: the key numbers
- Overall admit rate = 45.6% (73 of 160).
- Admit rate: research = 58.0% vs no research = 36.3%, so research helps.
- Mean GPA: admitted = 3.44 vs rejected = 3.16.
- Logistic fit: GPA b = 3.98 (OR ≈ 53.6 per whole GPA point), GRE b = 0.029, research b = 1.37 (OR ≈ 3.9). All three predictors point the right way.
Got your own numbers instead? Paste them into the Descriptives calculator for a full rundown, size your next study with the Power calculator, or format the result with the APA formatter.