Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 71 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<p align="center">
<a href="https://peterslijkhuis.github.io/StatLab/"><img src="docs/readme/hero.svg" alt="StatLab: learn statistics by doing it in R, right in your browser. 18 modules, 64 lessons, 89 exercises, 0 installs." width="100%"></a>
<a href="https://peterslijkhuis.github.io/StatLab/"><img src="docs/readme/hero.svg" alt="StatLab: learn statistics by doing it in R, right in your browser. 19 modules, 70 lessons, 94 exercises, 0 installs." width="100%"></a>
</p>

<p align="center">
Expand All @@ -24,7 +24,7 @@
</p>

<p align="center">
Built for psychology and business students at the <strong>University of Twente</strong>.<br>
Built for BMS bachelor students at the <strong>University of Twente</strong>, following the R taught in the Research Methods and Statistics courses.<br>
<sub>Made by dr. P.J.H. Slijkhuis and dr. V.d.C. Resendez Gomez, based on materials provided by dr. S.J. Watson. Theory, terminology and topic order follow Analysing Data Using Linear Models by S.M. van den Berg (5th ed., University of Twente, 2021; Creative Commons BY-NC-SA licence); the lessons are written independently.</sub>
</p>

Expand All @@ -49,7 +49,7 @@
</td>
<td width="33%" valign="top">
<h3>✅ Answers checked by R</h3>
89 exercises are marked by R itself. A wrong answer gets feedback on the <em>specific</em> mistake, not just a red cross.
94 exercises are marked by R itself. A wrong answer gets feedback on the <em>specific</em> mistake, not just a red cross.
</td>
<td width="33%" valign="top">
<h3>🧑‍🔬 An avatar that coaches</h3>
Expand Down Expand Up @@ -165,20 +165,22 @@ live in the browser, and export to a file that imports on any other computer.

## The course

**18 modules · 64 lessons · 89 checked exercises · 6 interactive simulations.**
From "what is a file path?" to mixed models, logistic regression, mediation and
**19 modules · 70 lessons · 94 checked exercises · 6 interactive simulations.**
From research questions and "what is a file path?" to mixed models, logistic regression, mediation and
Bayes. Statistics is taught the way the course team's own R workshops teach it:
in tidyverse style and through the linear model. `lm`, `lmer` and `glm` do the
work, and the t-test, ANOVA and chi-square appear as those same models under
their traditional names.

| | Module | What it covers | Simulation |
|---|---|---|---|
| **Research methods** | | | |
| RM | Research methods | Empirical research questions, units and variables, D-NOIR levels of measurement, sampling, crosstabs with epsilon, causality and the elaboration models, research designs and threats to validity | |
| **Foundations** | | | |
| 0 | Before you start | RStudio Projects, files, folders and paths, and what R's symbols mean, with a cheat sheet | |
| 1 | First steps in R | Objects, functions, help, packages and `library()` | |
| 2 | Working with data | `read.csv`, factors, the pipe, `select`, `filter`, `mutate`, wide and long data | |
| 3 | Describing data | `group_by` and `summarise`, mean versus median, surprises in a summary, scale scores and Cronbach's alpha | |
| 2 | Working with data | `read.csv`, factors and data types, the pipe, `select`, `filter`, `mutate`, wide and long data, missing values, recoding, joins, Excel and SPSS files | |
| 3 | Describing data | `group_by` and `summarise`, mean versus median, surprises in a summary, scale scores and Cronbach's alpha, exploratory factor analysis | |
| 4 | Visualising data | ggplot2 as layers, facets, and an APA-ready figure | |
| **Inference** | | | |
| 5 | The normal distribution | Density, z-scores and probabilities | Distribution |
Expand All @@ -193,9 +195,56 @@ their traditional names.
| 13 | Interactions and factorial designs | `a * b`, sum-to-zero contrasts, Type III tests with `car`, interaction plots | |
| 14 | Repeated measures and nested data | `lmer` with `(1 \| id)`, fixed and random effects, the paired t-test, group by time designs, pre, mid and post, Wilcoxon and Friedman tests | |
| 15 | Binary and count outcomes | `glm(..., family = binomial)`, log odds, odds ratios and reporting, Poisson regression for counts | |
| **Advanced** | | | |
| **Advanced** (switch on under Settings, Advanced topics) | | | |
| 16 | Bayesian statistics | Prior, likelihood and posterior, credible intervals, Bayes factors, Bayesian regression | |
| 17 | Mediation, factors and reports | Indirect effects with bootstrap intervals, exploratory factor analysis, reproducible reports with Quarto | |
| 17 | Mediation and reports | Indirect effects with bootstrap intervals, reproducible reports with Quarto | |

The Research methods module follows the BMS psychology course
*Introduction to Research Methodology* and H. van der Kolk's readers. Modules 0
to 15 follow van den Berg's book and the R taught in the BMS courses. Everything beyond them, the Advanced modules and a few sections
inside core lessons (Fisher's exact test, robust and bootstrap intervals,
nested random effects) and the model chooser's answers the course does not
teach, appears only after switching on **Advanced topics** under Settings.

### Read along in the book

Each lesson links to the chapter of the
[online book](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/index.html)
that covers it. The map lives in `src/content/reading.ts`, and a test checks
that every chapter is used.

| Ch | Topic (links to the chapter) | StatLab lessons |
|---|---|---|
| 1 | [Variables, variation and co-variation](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/intro.html) | RM-2, 2-1, 2-3, 3-1 to 3-3, 4-1 to 4-3, 5-1 to 5-3, 9-2 |
| 2 | [Inference about a mean](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/mean.html) | RM-3, 6-1 to 8-4 |
| 3 | [Inference about a proportion](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/prop.html) | 9-1 |
| 4 | [Simple and multiple regression](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/simple.html) | RM-4, 10-1, 10-2, 11-1, 11-2 |
| 5 | [Inference for linear models](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/inf-lm.html) | 10-3, 11-3 |
| 6 | [Categorical predictors](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/categorical.html) | 12-1, 12-2 |
| 7 | [Assumptions](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/assumptions.html) | 11-4 |
| 8 | [Non-parametric alternatives](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/nonpar1.html) | 10-4, 12-4 |
| 9 | [Moderation](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/moderation.html) | 13-1 to 13-3 |
| 10 | [Contrasts](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/contrasts.html) | 12-2, 13-2 |
| 11 | [Post-hoc comparisons](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/post-hoc.html) | 12-3 |
| 12 | [Linear mixed models](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/mixed.html) | 14-1 to 14-3 |
| 13 | [Pre, mid and post designs](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/premidpost.html) | 14-4 |
| 14 | [Non-parametric tests for repeated measures](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/nonpar2.html) | 14-5 |
| 15 | [Logistic regression](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/logistic.html) | 15-1 to 15-3 |
| 16 | [Poisson regression and chi-square](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/poissonrevised.html) | 9-3, 15-4 |
| A | [The normal distribution](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/appnormal.html) | 5-1 to 5-3 |
| A | [The t-distribution](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/appt.html) | 7-1, 8-2 |

Chapters of the BMS guide *Intro R for BMS Bachelor programs*: 1 (R and
RStudio) goes with Modules 0 to 2, 2 (handling data files) with Module 2,
3 and 4 (univariate and bivariate analysis) with Modules 3, 4, 9, 10 and 12,
5 (multivariate analysis) with Modules 11, 14 and 15, and 6 (psychometrics)
with Lessons 3-4 and 17-2.

The research methods lessons point to sections of Van der Kolk's *A short guide
to asking research questions, to hypothesis construction and to basic data
analysis using crosstabs*: 1 and 2 (research questions) with RM-1, 3 and 4
(units, variables and data matrices) with RM-2, 3 and 5 (crosstabs and
elaboration) with RM-4, and 1 (designs) with RM-5.

### How a lesson works

Expand Down Expand Up @@ -241,6 +290,19 @@ Theory, terminology and topic order follow
[Creative Commons BY-NC-SA licence](https://creativecommons.org/licenses/by-nc-sa/4.0/).
StatLab's lessons follow its theory, terminology and topic order but are
written independently.
Every lesson links to the chapters to read along in the
[online book](https://019c2310-d1f3-c202-b65d-2af52db09a6c.share.connect.posit.cloud/index.html).

The R lessons follow the R taught in the BMS Research Methods and Statistics
courses: the reference guide *Intro R for BMS Bachelor programs* (CODE staff,
BMS) and the [Intro R](https://jsteinrucke-intro-r.share.connect.posit.cloud/)
course. For help with your own research, ask the
[BMS Methodology Shop](https://www.utwente.nl/en/bms/m-store/).

The research methods lessons follow *Introduction to Research Methodology*
(BMS psychology bachelor, Module 1) and H. van der Kolk's readers *A short
guide to asking research questions, to hypothesis construction and to basic
data analysis using crosstabs* and *Decision making and empirical research*.

RStudio is a trademark of Posit Software, PBC. StatLab is not affiliated with
or endorsed by Posit.
Expand Down
6 changes: 3 additions & 3 deletions docs/readme/hero.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion e2e/accessibility.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { expect, test, type Page } from '@playwright/test';
// Scroll-in animations fade text from transparent, which axe would flag mid-fade.
test.use({ reducedMotion: 'reduce' });

const LESSONS = [...readFileSync('src/content/manifest.ts', 'utf8').matchAll(/id: '(\d\d-\d)'/g)].map((m) => m[1]);
const LESSONS = [...readFileSync('src/content/manifest.ts', 'utf8').matchAll(/id: '((?:\d\d|rm)-\d)'/g)].map((m) => m[1]);
const PAGES = ['./', './workspace', './which-model', './sample-size', './review', './avatar', ...LESSONS.map((id) => `./lesson/${id}`)];

async function violations(page: Page) {
Expand Down
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<meta name="theme-color" content="#f8fafc" />
<title>StatLab: data analysis with R</title>
<meta name="description" content="A free introductory statistics course in R that runs entirely in your browser: 18 modules, 64 lessons and 89 exercises checked by real R, with nothing to install." />
<meta name="description" content="A free introductory statistics course in R that runs entirely in your browser: 19 modules, 70 lessons and 94 exercises checked by real R, with nothing to install." />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<meta property="og:type" content="website" />
<meta property="og:title" content="StatLab: data analysis with R" />
<meta property="og:description" content="Learn statistics by doing it in R, right in your browser. 18 modules, 64 lessons, 89 exercises, nothing to install." />
<meta property="og:description" content="Learn statistics by doing it in R, right in your browser. 19 modules, 70 lessons, 94 exercises, nothing to install." />
<meta property="og:url" content="https://peterslijkhuis.github.io/StatLab/" />
<meta property="og:image" content="https://peterslijkhuis.github.io/StatLab/og-image.png" />
<meta property="og:image:width" content="1200" />
Expand Down
Binary file added public/Rplots.pdf
Binary file not shown.
7 changes: 7 additions & 0 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,13 @@ button.sidebar-lesson { width: 100%; border: 0; background: none; font: inherit;
.lesson-link.complete a::before { border-color: var(--success); background: var(--success); }
.lesson-link a:hover { color: var(--brand); }

.lesson-reading { margin: 0.4rem 0 0; font-size: 0.9rem; color: var(--muted); }
.advanced-note { margin: 1.2rem 0; padding: 0.6rem 0.9rem; border: 1px dashed var(--line-strong); border-radius: var(--radius-sm); color: var(--muted); font-size: 0.9rem; }
.advanced-section { margin: 1.2rem 0; padding: 0.2rem 1rem 0.6rem; border-left: 3px solid var(--line-strong); }
.advanced-label { margin: 0.6rem 0 0; color: var(--muted); font-size: 0.85rem; font-weight: 700; }
.home-help { margin-top: 3rem; padding: 1.4rem 1.5rem; border-radius: var(--radius); background: var(--surface); border: 1px solid var(--line); }
.home-help h2 { margin-top: 0; font-size: 1.2rem; }
.home-help p { color: var(--ink-2); margin-bottom: 0; }
.home-save { margin-top: 3rem; padding: 1.4rem 1.5rem; border-radius: var(--radius); background: var(--surface); border: 1px dashed var(--line-strong); }
.home-save h2 { margin-top: 0; font-size: 1.2rem; }
.home-save p { color: var(--ink-2); }
Expand Down
14 changes: 14 additions & 0 deletions src/components/Advanced.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { act, render, screen } from '@testing-library/react';
import { beforeEach, expect, test } from 'vitest';
import Advanced from './Advanced';
import { setAdvanced } from '../state/settings';

beforeEach(() => localStorage.clear());

test('an advanced section stays hidden behind a note until Advanced topics is on', () => {
render(<Advanced><p>Fisher's exact test</p></Advanced>);
expect(screen.queryByText("Fisher's exact test")).toBeNull();
expect(screen.getByText(/Switch on Advanced topics under Settings/)).toBeDefined();
act(() => setAdvanced(true));
expect(screen.getByText("Fisher's exact test")).toBeDefined();
});
25 changes: 25 additions & 0 deletions src/components/Advanced.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { ReactNode } from 'react';
import { useAdvanced } from '../state/settings';

/**
* A part of a lesson that goes beyond van den Berg's book and the BMS course
* materials. Shown only with Advanced topics switched on under Settings; until
* then a one-line note marks where it is. Never wrap an Exercise in it: a
* hidden exercise would keep the lesson from ever completing.
*/
export default function Advanced({ children }: { children: ReactNode }) {
const advanced = useAdvanced();
if (!advanced) {
return (
<p className="advanced-note">
<span aria-hidden="true">🎓 </span>An advanced section, beyond the book and the BMS course, is hidden here. Switch on Advanced topics under Settings to read it.
</p>
);
}
return (
<section className="advanced-section" aria-label="Advanced, beyond the course">
<p className="advanced-label"><span aria-hidden="true">🎓 </span>Advanced: beyond the book and the BMS course</p>
{children}
</section>
);
}
42 changes: 40 additions & 2 deletions src/components/Credits.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { MouseEvent } from 'react';
import { addBonusPoint } from '../state/progress';
import { BOOK_BASE } from '../content/reading';
import './Credits.css';

// Logo files are picked up from src/assets/logos by name, so adding
Expand All @@ -23,6 +24,25 @@ export const REFERENCE_BOOK = {
author: 'S.M. van den Berg',
href: 'https://ris.utwente.nl/ws/portalfiles/portal/253344321/Analysing_data_using_linear_models_5th_Ed_January_2021.pdf',
licenceHref: 'https://creativecommons.org/licenses/by-nc-sa/4.0/',
/** The book to read along in, online. */
onlineHref: `${BOOK_BASE}index.html`,
};

/** The R material BMS courses teach from, which the R lessons follow. */
export const R_MATERIALS = {
guide: { title: 'Intro R for BMS Bachelor programs', author: 'CODE staff, BMS' },
course: { title: 'Intro R', href: 'https://jsteinrucke-intro-r.share.connect.posit.cloud/' },
shop: { title: 'BMS Methodology Shop', href: 'https://www.utwente.nl/en/bms/m-store/' },
};

/** The research methods course's own readers, which the RM lessons follow. */
export const RM_MATERIALS = {
course: { title: 'Introduction to Research Methodology', where: 'BMS psychology bachelor, Module 1' },
shortGuide: {
title: 'A short guide to asking research questions, to hypothesis construction and to basic data analysis using crosstabs',
author: 'Van der Kolk',
},
decisionMaking: { title: 'Decision making and empirical research', author: 'Van der Kolk' },
};

export const PARTNERS = [
Expand Down Expand Up @@ -67,11 +87,29 @@ export default function Credits({ variant = 'full' }: Props) {
<a href={REFERENCE_BOOK.href} target="_blank" rel="noopener noreferrer">
<cite>{REFERENCE_BOOK.title}</cite>
</a>{' '}
by {REFERENCE_BOOK.author} (5th ed., University of Twente, 2021), licensed under a{' '}
by {REFERENCE_BOOK.author} (University of Twente; the online book is the 2024 edition), licensed under a{' '}
<a href={REFERENCE_BOOK.licenceHref} target="_blank" rel="noopener noreferrer">
Creative Commons BY-NC-SA licence
</a>
. StatLab's lessons are written independently.
. Read it along with the course in the{' '}
<a href={REFERENCE_BOOK.onlineHref} target="_blank" rel="noopener noreferrer">online book</a>.
StatLab's lessons are written independently.
</p>
)}
{variant === 'full' && (
<p className="credits-book">
The R lessons follow the R taught in the BMS Research Methods and Statistics courses: the reference guide{' '}
<cite>{R_MATERIALS.guide.title}</cite> ({R_MATERIALS.guide.author}) and the{' '}
<a href={R_MATERIALS.course.href} target="_blank" rel="noopener noreferrer">{R_MATERIALS.course.title}</a>{' '}
course. For help with your own research, ask the{' '}
<a href={R_MATERIALS.shop.href} target="_blank" rel="noopener noreferrer">{R_MATERIALS.shop.title}</a>.
</p>
)}
{variant === 'full' && (
<p className="credits-book">
The research methods lessons follow <cite>{RM_MATERIALS.course.title}</cite> ({RM_MATERIALS.course.where})
and H. van der Kolk's readers{' '}
<cite>{RM_MATERIALS.shortGuide.title}</cite> and <cite>{RM_MATERIALS.decisionMaking.title}</cite>.
</p>
)}
{variant === 'full' && (
Expand Down
Loading