RSM2074 Lecture Week 9
Parametric: Statistics based on parameters (Mean & SD)
{
const x = d3.range(40, 160, 0.5);
const y = x.map(xi => (1 / (paramSD * Math.sqrt(2 * Math.PI))) *
Math.exp(-0.5 * Math.pow((xi - paramMean) / paramSD, 2)));
return html`
<div style="text-align: center;">
${Plot.plot({
marks: [
Plot.areaY(x.map((xi, i) => ({x: xi, y: y[i]})), {
x: "x", y: "y", fill: "steelblue", fillOpacity: 0.3
}),
Plot.line(x.map((xi, i) => ({x: xi, y: y[i]})), {
x: "x", y: "y", stroke: "steelblue", strokeWidth: 3
}),
Plot.ruleX([paramMean], {stroke: "red", strokeWidth: 3}),
Plot.ruleX([paramMean - paramSD, paramMean + paramSD], {stroke: "orange", strokeWidth: 2, strokeDasharray: "4,4"})
],
x: {label: "IQ Score", domain: [40, 160]},
y: {label: "Probability"},
grid: true,
width: 700,
height: 350
})}
<div style="display: flex; justify-content: space-around; margin-top: 15px; font-size: 18px;">
<div style="background: #e74c3c; color: white; padding: 12px 20px; border-radius: 8px;">
<strong>MEAN</strong> = ${paramMean}
</div>
<div style="background: #3498db; color: white; padding: 12px 20px; border-radius: 8px;">
<strong>SD</strong> = ${paramSD}
</div>
</div>
</div>`;
}Shapiro-Wilk & Kolmogorov-Smirnov tests
{
const data = [];
for(let i = 0; i < 200; i++) {
let val;
if(distShape === "Normal") {
val = d3.randomNormal(10, 3)();
} else if(distShape === "Right Skewed") {
val = Math.pow(Math.random(), 3) * 20;
} else {
val = 20 - Math.pow(Math.random(), 3) * 20;
}
data.push(val);
}
const isNormal = distShape === "Normal";
return html`
<div style="text-align: center;">
${Plot.plot({
marks: [
Plot.rectY(data, Plot.binX({y: "count"}, {
x: d => d,
fill: isNormal ? "#2ecc71" : "#e74c3c",
thresholds: 25
}))
],
x: {label: "Value"},
y: {label: "Frequency"},
grid: true,
width: 700,
height: 320
})}
<div style="display: flex; gap: 12px; justify-content: center; margin-top: 12px;">
<div style="background: ${isNormal ? '#e8f5e9' : '#ffebee'}; padding: 10px; border-radius: 8px; font-size: 15px; border: 2px solid ${isNormal ? '#4caf50' : '#f44336'};">
<strong>Shapiro-Wilk:</strong> ${isNormal ? 'p > .05 ✓' : 'p < .05 ⚠️'}
</div>
<div style="background: ${isNormal ? '#e8f5e9' : '#ffebee'}; padding: 10px; border-radius: 8px; font-size: 15px; border: 2px solid ${isNormal ? '#4caf50' : '#f44336'};">
<strong>K-S Test:</strong> ${isNormal ? 'p > .05 ✓' : 'p < .05 ⚠️'}
</div>
<div style="background: #fff3e0; padding: 10px; border-radius: 8px; font-size: 15px;">
${isNormal ? 'Parametric OK' : 'Use Non-parametric'}
</div>
</div>
</div>`;
}Null hypothesis (H₀): Data comes from a normally distributed population
When parametric assumptions are violated:
Trade-off:
html`<div style="display: flex; gap: 25px; justify-content: center;">
<div style="flex: 1; background: #e8f5e9; padding: 25px; border-radius: 10px; border-left: 5px solid #4caf50; max-width: 400px;">
<div style="font-size: 20px; font-weight: bold; margin-bottom: 15px; color: #2e7d32;">
Continuous
</div>
<div style="font-size: 18px; line-height: 1.7;">
• Test scores (0-100)<br/>
• Running speed (km/h)<br/>
• Reaction time (ms)<br/>
• Amount consumed
</div>
</div>
<div style="flex: 1; background: #fff3e0; padding: 25px; border-radius: 10px; border-left: 5px solid #ff9800; max-width: 400px;">
<div style="font-size: 20px; font-weight: bold; margin-bottom: 15px; color: #e65100;">
Categorical
</div>
<div style="font-size: 18px; line-height: 1.7;">
• Coffee or Tea<br/>
• Male or Female<br/>
• Heads or Tails<br/>
• Preferred brand
</div>
</div>
</div>`Categorical → Chi-Square | Continuous → t-test, ANOVA
Compares Observed vs Expected frequencies
{
return html`
<div style="text-align: center;">
<div style="display: flex; gap: 30px; justify-content: center; margin: 40px 0;">
<div style="flex: 1; background: #e3f2fd; padding: 30px; border-radius: 10px; max-width: 350px;">
<div style="font-size: 32px; font-weight: bold; color: #1976d2; margin-bottom: 15px;">O</div>
<div style="font-size: 20px;">
<strong>Observed</strong><br/>
What you measured<br/>from your data
</div>
</div>
<div style="flex: 1; background: #f3e5f5; padding: 30px; border-radius: 10px; max-width: 350px;">
<div style="font-size: 32px; font-weight: bold; color: #7b1fa2; margin-bottom: 15px;">E</div>
<div style="font-size: 20px;">
<strong>Expected</strong><br/>
What you'd expect<br/>by chance (if H₀ true)
</div>
</div>
</div>
<div style="font-size: 28px; background: #fff9c4; padding: 25px; border-radius: 10px; max-width: 600px; margin: 0 auto;">
<strong>χ² = Σ[(O - E)² / E]</strong>
</div>
</div>`;
}Null Hypothesis (H₀): Observed frequencies match Expected frequencies
Alternative Hypothesis (H₁): Observed frequencies differ from Expected
html`<div style="display: flex; flex-direction: column; gap: 20px; margin: 20px;">
<div style="background: #e8f5e9; padding: 25px; border-radius: 10px; border-left: 6px solid #4caf50;">
<div style="font-size: 22px; font-weight: bold; margin-bottom: 12px; color: #2e7d32;">
1. Goodness of Fit
</div>
<div style="font-size: 19px;">
<strong>ONE</strong> categorical variable | <em>"Is my coin fair?"</em>
</div>
</div>
<div style="background: #e3f2fd; padding: 25px; border-radius: 10px; border-left: 6px solid #2196f3;">
<div style="font-size: 22px; font-weight: bold; margin-bottom: 12px; color: #1565c0;">
2. Test of Independence
</div>
<div style="font-size: 19px;">
<strong>TWO+</strong> categorical variables | <em>"Does preference depend on age?"</em>
</div>
</div>
</div>`Identify the correct test for each scenario:
{
const scenarios = {
"Scenario 1: Coffee vs Tea": {
question: "150 people: Do more prefer coffee over tea?",
answer: "Goodness of Fit",
reason: "ONE variable (beverage)",
color: "#4caf50"
},
"Scenario 2: Amount of coffee": {
question: "Does amount differ between drinkers vs non-drinkers?",
answer: "NOT Chi-square (use t-test)",
reason: "Amount is CONTINUOUS",
color: "#f44336"
},
"Scenario 3: Fair dice?": {
question: "Roll 60 times, check if each face appears equally",
answer: "Goodness of Fit",
reason: "ONE variable (dice face)",
color: "#4caf50"
},
"Scenario 4: Preference by ethnicity": {
question: "Does coffee vs tea preference depend on ethnicity?",
answer: "Test of Independence",
reason: "TWO variables",
color: "#2196f3"
},
"Scenario 5: Brand by country": {
question: "Does car brand preference depend on country?",
answer: "Test of Independence",
reason: "TWO variables",
color: "#2196f3"
}
};
const s = scenarios[scenario];
return html`
<div style="text-align: center; padding: 20px;">
<div style="background: #f8f9fa; padding: 25px; border-radius: 10px; margin-bottom: 20px;">
<div style="font-size: 20px; font-weight: bold; margin-bottom: 15px;">
${scenario}
</div>
<div style="font-size: 17px;">
${s.question}
</div>
</div>
<div style="background: ${s.color}; color: white; padding: 30px; border-radius: 10px; margin-bottom: 20px;">
<div style="font-size: 26px; font-weight: bold;">
${s.answer}
</div>
</div>
<div style="background: #fff9c4; padding: 25px; border-radius: 10px; font-size: 19px; text-align: left;">
<strong>Why?</strong> ${s.reason}
</div>
</div>`;
}Does my observed data match expected distribution?
html`<div style="text-align: center;">
<div style="display: flex; gap: 30px; justify-content: center; margin: 20px;">
<div style="background: #e3f2fd; padding: 20px; border-radius: 10px; max-width: 280px;">
<div style="font-size: 19px; font-weight: bold; margin-bottom: 15px; color: #1976d2;">Expected</div>
<div style="font-size: 17px;">What theory predicts OR random chance gives</div>
</div>
<div style="background: #fff3e0; padding: 20px; border-radius: 10px; max-width: 280px;">
<div style="font-size: 19px; font-weight: bold; margin-bottom: 15px; color: #e65100;">Observed</div>
<div style="font-size: 17px;">What you actually measured in sample</div>
</div>
</div>
<div style="background: #e8f5e9; padding: 20px; border-radius: 10px; margin-top: 20px; max-width: 600px; margin-left: auto; margin-right: auto;">
<div style="font-size: 19px;"><strong>Question:</strong> Is the difference just random variation?</div>
</div>
</div>`Simple example with equal expected frequencies
{
return html`
<div style="text-align: center;">
<div style="display: flex; gap: 20px; justify-content: center; margin: 20px;">
<div style="background: #e3f2fd; padding: 20px; border-radius: 10px; max-width: 280px;">
<div style="font-size: 19px; font-weight: bold; margin-bottom: 10px; color: #1976d2;">Expected</div>
<div style="font-size: 17px;">If fair: 50 heads<br/>50 tails (out of 100)</div>
</div>
<div style="background: #fff3e0; padding: 20px; border-radius: 10px; max-width: 280px;">
<div style="font-size: 19px; font-weight: bold; margin-bottom: 10px; color: #e65100;">Observed</div>
<div style="font-size: 17px;">I got: 60 heads<br/>40 tails (out of 100)</div>
</div>
</div>
<div style="background: #fff9c4; padding: 20px; border-radius: 10px; margin-top: 20px; max-width: 600px; margin-left: auto; margin-right: auto;">
<strong>H₀:</strong> Coin is fair | <strong>H₁:</strong> Coin is biased
</div>
</div>`;
}{
coinButton;
const flips = Array.from({length: coinFlips}, () => Math.random() > 0.5 ? 1 : 0);
const heads = flips.filter(f => f === 1).length;
const tails = coinFlips - heads;
const expected = coinFlips / 2;
const chisqCoin = Math.pow(heads - expected, 2) / expected + Math.pow(tails - expected, 2) / expected;
const critical = 3.84;
return html`
<div style="text-align: center;">
${Plot.plot({
marks: [
Plot.barY([
{side: "Heads", count: heads},
{side: "Tails", count: tails}
], {x: "side", y: "count", fill: "#667eea"}),
Plot.ruleY([expected], {stroke: "orange", strokeWidth: 3, strokeDasharray: "6,3"})
],
x: {label: "Coin Side"},
y: {label: "Count", domain: [0, Math.max(heads, tails) + 20]},
width: 650,
height: 300
})}
<div style="display: flex; gap: 15px; justify-content: center; margin-top: 15px;">
<div style="background: #e3f2fd; padding: 12px; border-radius: 8px; font-size: 16px;">
<strong>Expected:</strong> ${expected.toFixed(0)} each
</div>
<div style="background: ${chisqCoin > critical ? '#ffebee' : '#e8f5e9'}; padding: 12px; border-radius: 8px; font-size: 16px; border: 2px solid ${chisqCoin > critical ? '#f44336' : '#4caf50'};">
<strong>χ² = ${chisqCoin.toFixed(2)}</strong> ${chisqCoin > critical ? '(biased)' : '(fair)'}
</div>
</div>
</div>`;
}See how deviations accumulate into χ²:
{
const total = obsCats + obsDogs + obsMice;
// Expected ratio: 3:2:1 (so 50% Cats, 33.3% Dogs, 16.7% Mice)
const expCats = (3/6) * total;
const expDogs = (2/6) * total;
const expMice = (1/6) * total;
const chisqAnim = Math.pow(obsCats - expCats, 2) / expCats +
Math.pow(obsDogs - expDogs, 2) / expDogs +
Math.pow(obsMice - expMice, 2) / expMice;
const critical = 5.99;
const maxVal = Math.max(obsCats, obsDogs, obsMice, expCats, expDogs, expMice);
// Calculate percentages
const obsCatPct = ((obsCats / total) * 100).toFixed(1);
const obsDogPct = ((obsDogs / total) * 100).toFixed(1);
const obsMicePct = ((obsMice / total) * 100).toFixed(1);
return html`
<div style="text-align: center;">
<div style="font-size: 17px; background: #f8f9fa; padding: 12px; border-radius: 8px; margin-bottom: 12px;">
<strong>Expected ratio: 50% Cats : 33% Dogs : 17% Mice</strong><br/>
<strong>Your observed:</strong> ${obsCatPct}% Cats, ${obsDogPct}% Dogs, ${obsMicePct}% Mice
</div>
${Plot.plot({
marks: [
Plot.barY([
{animal: "Cats", type: "Expected", val: expCats},
{animal: "Cats", type: "Observed", val: obsCats},
{animal: "Dogs", type: "Expected", val: expDogs},
{animal: "Dogs", type: "Observed", val: obsDogs},
{animal: "Mice", type: "Expected", val: expMice},
{animal: "Mice", type: "Observed", val: obsMice}
], {
x: "animal",
y: "val",
fill: "type",
fx: "animal"
})
],
fx: {label: "Animal"},
y: {label: "Count", domain: [0, maxVal + 5]},
color: {
domain: ["Expected", "Observed"],
range: ["#3498db", "#e74c3c"]
},
width: 650,
height: 260
})}
<div style="margin-top: 12px; display: flex; gap: 12px; justify-content: center;">
<div style="background: #e3f2fd; padding: 10px; border-radius: 8px; font-size: 15px;">
<strong>χ² = ${chisqAnim.toFixed(2)}</strong>
</div>
<div style="background: ${chisqAnim > critical ? '#ffebee' : '#e8f5e9'}; padding: 10px; border-radius: 8px; font-size: 15px; border: 2px solid ${chisqAnim > critical ? '#f44336' : '#4caf50'};">
${chisqAnim > critical ? 'Reject H₀ (χ² > 5.99)' : 'Fail to reject H₀ (χ² ≤ 5.99)'}
</div>
</div>
</div>`;
}Keep expected constant, adjust observed:
{
const expRed = 10;
const expBlue = 90;
const diffRed = obsRed - expRed;
const diffBlue = obsBlue - expBlue;
const diffSqRed = Math.pow(diffRed, 2);
const diffSqBlue = Math.pow(diffBlue, 2);
const cellRed = diffSqRed / expRed;
const cellBlue = diffSqBlue / expBlue;
const chisq = cellRed + cellBlue;
return html`
<div style="text-align: center;">
<div style="font-size: 17px; background: #f8f9fa; padding: 12px; border-radius: 8px; margin-bottom: 15px;">
<strong>Marble bag:</strong> Expected 10 Red, 90 Blue
</div>
<table style="margin: 0 auto; border-collapse: collapse; box-shadow: 0 2px 8px rgba(0,0,0,0.1); font-size: 15px;">
<thead style="background: #667eea; color: white;">
<tr>
<th style="padding: 8px; border: 1px solid #ddd;"></th>
<th style="padding: 8px; border: 1px solid #ddd;">E</th>
<th style="padding: 8px; border: 1px solid #ddd;">O</th>
<th style="padding: 8px; border: 1px solid #ddd;">O-E</th>
<th style="padding: 8px; border: 1px solid #ddd;">(O-E)²</th>
<th style="padding: 8px; border: 1px solid #ddd;">(O-E)²/E</th>
</tr>
</thead>
<tbody style="background: white;">
<tr>
<td style="padding: 7px; border: 1px solid #ddd; font-weight: bold;">Red</td>
<td style="padding: 7px; border: 1px solid #ddd;">10</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #fff3e0;">${obsRed}</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e3f2fd;">${diffRed > 0 ? '+' : ''}${diffRed}</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e3f2fd;">${diffSqRed}</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e8f5e9;"><strong>${cellRed.toFixed(2)}</strong></td>
</tr>
<tr>
<td style="padding: 7px; border: 1px solid #ddd; font-weight: bold;">Blue</td>
<td style="padding: 7px; border: 1px solid #ddd;">90</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #fff3e0;">${obsBlue}</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e3f2fd;">${diffBlue > 0 ? '+' : ''}${diffBlue}</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e3f2fd;">${diffSqBlue}</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e8f5e9;"><strong>${cellBlue.toFixed(2)}</strong></td>
</tr>
</tbody>
</table>
<div style="font-size: 20px; background: #e8f5e9; padding: 12px; border-radius: 10px; margin-top: 12px;">
<strong>χ² = ${cellRed.toFixed(2)} + ${cellBlue.toFixed(2)} = ${chisq.toFixed(2)}</strong>
</div>
</div>`;
}Survey of 120 students - Expected frequencies:
html`<div style="text-align: center;">
<div style="background: #fff9c4; padding: 15px; border-radius: 10px; margin-bottom: 15px;">
<div style="font-size: 18px; font-weight: bold;">
Four majors with 30 students expected in each
</div>
</div>
<table style="margin: 0 auto; border-collapse: collapse; box-shadow: 0 2px 8px rgba(0,0,0,0.1); font-size: 15px;">
<thead style="background: #667eea; color: white;">
<tr>
<th style="padding: 8px; border: 1px solid #ddd;">Major</th>
<th style="padding: 8px; border: 1px solid #ddd;">Expected</th>
<th style="padding: 8px; border: 1px solid #ddd;">Observed</th>
</tr>
</thead>
<tbody style="background: white;">
<tr>
<td style="padding: 7px; border: 1px solid #ddd; font-weight: bold;">Psychology</td>
<td style="padding: 7px; border: 1px solid #ddd;">30</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #fff3e0;">40</td>
</tr>
<tr>
<td style="padding: 7px; border: 1px solid #ddd; font-weight: bold;">Business</td>
<td style="padding: 7px; border: 1px solid #ddd;">30</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #fff3e0;">35</td>
</tr>
<tr>
<td style="padding: 7px; border: 1px solid #ddd; font-weight: bold;">Engineering</td>
<td style="padding: 7px; border: 1px solid #ddd;">30</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #fff3e0;">25</td>
</tr>
<tr>
<td style="padding: 7px; border: 1px solid #ddd; font-weight: bold;">Arts</td>
<td style="padding: 7px; border: 1px solid #ddd;">30</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #fff3e0;">20</td>
</tr>
</tbody>
</table>
</div>`Calculate differences for each major:
html`<div style="text-align: center;">
<table style="margin: 0 auto; border-collapse: collapse; box-shadow: 0 2px 8px rgba(0,0,0,0.1); font-size: 15px;">
<thead style="background: #667eea; color: white;">
<tr>
<th style="padding: 8px; border: 1px solid #ddd;">Major</th>
<th style="padding: 8px; border: 1px solid #ddd;">O</th>
<th style="padding: 8px; border: 1px solid #ddd;">E</th>
<th style="padding: 8px; border: 1px solid #ddd;">O-E</th>
<th style="padding: 8px; border: 1px solid #ddd;">(O-E)²</th>
</tr>
</thead>
<tbody style="background: white;">
<tr>
<td style="padding: 7px; border: 1px solid #ddd; font-weight: bold;">Psych</td>
<td style="padding: 7px; border: 1px solid #ddd;">40</td>
<td style="padding: 7px; border: 1px solid #ddd;">30</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e3f2fd;">10</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e3f2fd;">100</td>
</tr>
<tr>
<td style="padding: 7px; border: 1px solid #ddd; font-weight: bold;">Business</td>
<td style="padding: 7px; border: 1px solid #ddd;">35</td>
<td style="padding: 7px; border: 1px solid #ddd;">30</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e3f2fd;">5</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e3f2fd;">25</td>
</tr>
<tr>
<td style="padding: 7px; border: 1px solid #ddd; font-weight: bold;">Eng</td>
<td style="padding: 7px; border: 1px solid #ddd;">25</td>
<td style="padding: 7px; border: 1px solid #ddd;">30</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e3f2fd;">-5</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e3f2fd;">25</td>
</tr>
<tr>
<td style="padding: 7px; border: 1px solid #ddd; font-weight: bold;">Arts</td>
<td style="padding: 7px; border: 1px solid #ddd;">20</td>
<td style="padding: 7px; border: 1px solid #ddd;">30</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e3f2fd;">-10</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e3f2fd;">100</td>
</tr>
</tbody>
</table>
</div>`Divide by expected to get final χ² components:
html`<div style="text-align: center;">
<table style="margin: 0 auto; border-collapse: collapse; box-shadow: 0 2px 8px rgba(0,0,0,0.1); font-size: 15px;">
<thead style="background: #667eea; color: white;">
<tr>
<th style="padding: 8px; border: 1px solid #ddd;">Major</th>
<th style="padding: 8px; border: 1px solid #ddd;">(O-E)²</th>
<th style="padding: 8px; border: 1px solid #ddd;">E</th>
<th style="padding: 8px; border: 1px solid #ddd;">(O-E)²/E</th>
</tr>
</thead>
<tbody style="background: white;">
<tr>
<td style="padding: 7px; border: 1px solid #ddd; font-weight: bold;">Psych</td>
<td style="padding: 7px; border: 1px solid #ddd;">100</td>
<td style="padding: 7px; border: 1px solid #ddd;">30</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e8f5e9;">3.33</td>
</tr>
<tr>
<td style="padding: 7px; border: 1px solid #ddd; font-weight: bold;">Business</td>
<td style="padding: 7px; border: 1px solid #ddd;">25</td>
<td style="padding: 7px; border: 1px solid #ddd;">30</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e8f5e9;">0.83</td>
</tr>
<tr>
<td style="padding: 7px; border: 1px solid #ddd; font-weight: bold;">Eng</td>
<td style="padding: 7px; border: 1px solid #ddd;">25</td>
<td style="padding: 7px; border: 1px solid #ddd;">30</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e8f5e9;">0.83</td>
</tr>
<tr>
<td style="padding: 7px; border: 1px solid #ddd; font-weight: bold;">Arts</td>
<td style="padding: 7px; border: 1px solid #ddd;">100</td>
<td style="padding: 7px; border: 1px solid #ddd;">30</td>
<td style="padding: 7px; border: 1px solid #ddd; background: #e8f5e9;">3.33</td>
</tr>
</tbody>
</table>
<div style="font-size: 20px; background: #e8f5e9; padding: 12px; border-radius: 10px; margin-top: 12px;">
<strong>χ² = 3.33 + 0.83 + 0.83 + 3.33 = 8.32</strong>
</div>
</div>`Try different numbers of categories:
{
const k = numCat;
const df = k - 1;
return html`
<div style="text-align: center;">
<div style="display: flex; gap: 20px; justify-content: center; margin: 20px;">
<div style="background: #e3f2fd; padding: 20px; border-radius: 10px;">
<div style="font-size: 32px; font-weight: bold; color: #1976d2; margin-bottom: 10px;">
${k}
</div>
<div style="font-size: 16px;">
Total categories
</div>
</div>
<div style="background: #e8f5e9; padding: 20px; border-radius: 10px;">
<div style="font-size: 32px; font-weight: bold; color: #4caf50; margin-bottom: 10px;">
${df}
</div>
<div style="font-size: 16px;">
Degrees of freedom (k-1)
</div>
</div>
</div>
<div style="background: #fff9c4; padding: 15px; border-radius: 10px; margin-top: 15px; max-width: 650px; margin-left: auto; margin-right: auto;">
<div style="font-size: 16px; line-height: 1.6;">
<strong>Example:</strong> If you know frequencies for ${k-1} categories,<br/>
the last category is determined by the total<br/>
(it's "not free to vary")
</div>
</div>
</div>`;
}Same χ² can mean different things with different df:
{
const df = dfChoice;
const chi = chiValue;
// Critical values at p = .05 for different df
const criticals = {
1: 3.84,
2: 5.99,
3: 7.81,
4: 9.49,
5: 11.07
};
const critical = criticals[df];
const significant = chi > critical;
return html`
<div style="text-align: center;">
<div style="background: #f8f9fa; padding: 15px; border-radius: 10px; margin-bottom: 15px;">
<div style="font-size: 18px;">
<strong>Your values:</strong> χ² = ${chi.toFixed(2)}, df = ${df}
</div>
</div>
<div style="display: flex; gap: 20px; justify-content: center; margin: 20px;">
<div style="background: #e3f2fd; padding: 20px; border-radius: 10px;">
<div style="font-size: 28px; font-weight: bold; color: #1976d2; margin-bottom: 10px;">
${chi.toFixed(2)}
</div>
<div style="font-size: 16px;">
Observed χ²
</div>
</div>
<div style="background: #fff3e0; padding: 20px; border-radius: 10px;">
<div style="font-size: 28px; font-weight: bold; color: #e65100; margin-bottom: 10px;">
${critical.toFixed(2)}
</div>
<div style="font-size: 16px;">
Critical value (df=${df})
</div>
</div>
</div>
<div style="background: ${significant ? '#e8f5e9' : '#ffebee'}; padding: 20px; border-radius: 10px; border: 3px solid ${significant ? '#4caf50' : '#f44336'};">
<div style="font-size: 22px; font-weight: bold; margin-bottom: 10px;">
${significant ? '✓ Significant Result' : '✗ Not Significant'}
</div>
<div style="font-size: 17px;">
${significant ?
`χ² (${chi.toFixed(2)}) > critical (${critical.toFixed(2)}) → Reject H₀` :
`χ² (${chi.toFixed(2)}) ≤ critical (${critical.toFixed(2)}) → Fail to reject H₀`}
</div>
</div>
</div>`;
}Does Variable A’s distribution depend on Variable B?
html`<div style="text-align: center;">
<div style="display: flex; gap: 20px; justify-content: center; margin: 15px;">
<div style="background: #e3f2fd; padding: 18px; border-radius: 10px; max-width: 280px;">
<div style="font-size: 19px; font-weight: bold; margin-bottom: 10px; color: #1976d2;">Variable 1</div>
<div style="font-size: 17px;">Coffee or Tea?</div>
</div>
<div style="background: #f3e5f5; padding: 18px; border-radius: 10px; max-width: 280px;">
<div style="font-size: 19px; font-weight: bold; margin-bottom: 10px; color: #7b1fa2;">Variable 2</div>
<div style="font-size: 17px;">1st or 4th year?</div>
</div>
</div>
<div style="background: #fff9c4; padding: 15px; border-radius: 10px; margin-top: 15px; max-width: 650px; margin-left: auto; margin-right: auto;">
<div style="font-size: 18px;"><strong>Question:</strong> Does beverage depend on year?</div>
</div>
</div>`Start with totals, cells to be determined:
{
return html`
<div style="text-align: center;">
<div style="font-size: 18px; font-weight: bold; margin-bottom: 12px;">
Survey Results: 60 students (cells unknown)
</div>
<table style="margin: 0 auto; border-collapse: collapse; box-shadow: 0 2px 8px rgba(0,0,0,0.1); font-size: 16px;">
<thead style="background: #667eea; color: white;">
<tr>
<th style="padding: 10px; border: 1px solid #ddd;"></th>
<th style="padding: 10px; border: 1px solid #ddd;">1st Yr</th>
<th style="padding: 10px; border: 1px solid #ddd;">4th Yr</th>
<th style="padding: 10px; border: 1px solid #ddd;">Total</th>
</tr>
</thead>
<tbody style="background: white;">
<tr>
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Coffee</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #f0f0f0;">?</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #f0f0f0;">?</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #fff3e0;">35</td>
</tr>
<tr>
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Tea</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #f0f0f0;">?</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #f0f0f0;">?</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #fff3e0;">25</td>
</tr>
<tr style="background: #e8f5e9;">
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Total</td>
<td style="padding: 8px; border: 1px solid #ddd;">35</td>
<td style="padding: 8px; border: 1px solid #ddd;">25</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #667eea; color: white;">60</td>
</tr>
</tbody>
</table>
</div>`;
}Key insight: Each cell depends on row and column totals
html`<div style="text-align: center; padding: 15px;">
<div style="font-size: 30px; background: #e8f5e9; padding: 20px; border-radius: 10px; max-width: 700px; margin: 0 auto; font-weight: bold; margin-bottom: 25px;">
E = (Row Total × Column Total) / Grand Total
</div>
<div style="background: #e3f2fd; padding: 20px; border-radius: 10px; max-width: 750px; margin: 0 auto;">
<div style="font-size: 17px; line-height: 1.7; text-align: left;">
<strong>Example: 1st year students who prefer coffee</strong><br/><br/>
<strong>Row total (Coffee drinkers):</strong> 35 students<br/>
<strong>Column total (1st year):</strong> 35 students<br/>
<strong>Grand total:</strong> 60 students<br/><br/>
<strong style="color: #1976d2;">E = (35 × 35) / 60 = 1225 / 60 = 20.42</strong><br/><br/>
<strong>Meaning:</strong> If beverage doesn't depend on year,<br/>
we expect 20.42 first-year students to prefer coffee
</div>
</div>
</div>`Breaking down each cell calculation:
html`<div style="text-align: center;">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 13px; max-width: 750px; margin: 0 auto;">
<div style="background: #e3f2fd; padding: 15px; border-radius: 10px;">
<div style="font-size: 16px; font-weight: bold; margin-bottom: 8px;">1st Yr & Coffee</div>
<div style="font-size: 14px; line-height: 1.5;">
E = (35 × 35) / 60<br/>
<strong style="color: #1976d2;">= 20.42</strong>
</div>
</div>
<div style="background: #e3f2fd; padding: 15px; border-radius: 10px;">
<div style="font-size: 16px; font-weight: bold; margin-bottom: 8px;">4th Yr & Coffee</div>
<div style="font-size: 14px; line-height: 1.5;">
E = (35 × 25) / 60<br/>
<strong style="color: #1976d2;">= 14.58</strong>
</div>
</div>
<div style="background: #fff3e0; padding: 15px; border-radius: 10px;">
<div style="font-size: 16px; font-weight: bold; margin-bottom: 8px;">1st Yr & Tea</div>
<div style="font-size: 14px; line-height: 1.5;">
E = (25 × 35) / 60<br/>
<strong style="color: #e65100;">= 14.58</strong>
</div>
</div>
<div style="background: #fff3e0; padding: 15px; border-radius: 10px;">
<div style="font-size: 16px; font-weight: bold; margin-bottom: 8px;">4th Yr & Tea</div>
<div style="font-size: 14px; line-height: 1.5;">
E = (25 × 25) / 60<br/>
<strong style="color: #e65100;">= 10.42</strong>
</div>
</div>
</div>
<div style="background: #fff9c4; padding: 12px; border-radius: 10px; margin-top: 15px; font-size: 15px;">
<strong>Check:</strong> 20.42 + 14.58 + 14.58 + 10.42 = 60 ✓
</div>
</div>`Adjust totals and see how expected changes:
{
const grandTotal = 60;
const teaTotal = grandTotal - cafTotal;
const yr4Total = grandTotal - yr1Total;
const e11 = (cafTotal * yr1Total) / grandTotal;
const e12 = (cafTotal * yr4Total) / grandTotal;
const e21 = (teaTotal * yr1Total) / grandTotal;
const e22 = (teaTotal * yr4Total) / grandTotal;
const cafPct = (cafTotal / grandTotal * 100).toFixed(0);
const yr1Pct = (yr1Total / grandTotal * 100).toFixed(0);
return html`
<div style="text-align: center;">
<div style="font-size: 17px; background: #f8f9fa; padding: 12px; border-radius: 8px; margin-bottom: 15px;">
<strong>${cafPct}% prefer coffee | ${yr1Pct}% are 1st year</strong>
</div>
<table style="margin: 0 auto; border-collapse: collapse; box-shadow: 0 2px 8px rgba(0,0,0,0.1); font-size: 15px;">
<thead style="background: #2ecc71; color: white;">
<tr>
<th style="padding: 8px; border: 1px solid #ddd;"></th>
<th style="padding: 8px; border: 1px solid #ddd;">1st Yr</th>
<th style="padding: 8px; border: 1px solid #ddd;">4th Yr</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Coffee</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e8f5e9;">${e11.toFixed(2)}</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e8f5e9;">${e12.toFixed(2)}</td>
</tr>
<tr>
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Tea</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e8f5e9;">${e21.toFixed(2)}</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e8f5e9;">${e22.toFixed(2)}</td>
</tr>
</tbody>
</table>
<div style="background: #fff9c4; padding: 12px; border-radius: 8px; margin-top: 12px; font-size: 15px;">
<strong>If independent:</strong> We expect ${e11.toFixed(1)} first-year coffee drinkers
</div>
</div>`;
}Change observed and watch expected update:
viewof cell11 = Inputs.range([0, 50], {value: 20, step: 1, label: "1st & Coffee:"})
viewof cell12 = Inputs.range([0, 50], {value: 15, step: 1, label: "4th & Coffee:"})
viewof cell21 = Inputs.range([0, 50], {value: 15, step: 1, label: "1st & Tea:"})
viewof cell22 = Inputs.range([0, 50], {value: 10, step: 1, label: "4th & Tea:"}){
const r1 = cell11 + cell12;
const r2 = cell21 + cell22;
const c1 = cell11 + cell21;
const c2 = cell12 + cell22;
const n = r1 + r2;
const e11 = (r1 * c1) / n;
const e12 = (r1 * c2) / n;
const e21 = (r2 * c1) / n;
const e22 = (r2 * c2) / n;
const chisq2x2 = Math.pow(cell11 - e11, 2) / e11 +
Math.pow(cell12 - e12, 2) / e12 +
Math.pow(cell21 - e21, 2) / e21 +
Math.pow(cell22 - e22, 2) / e22;
const critical2x2 = 3.84;
return html`
<div style="text-align: center;">
<div style="display: flex; gap: 15px; justify-content: center; margin-bottom: 15px;">
<div>
<div style="font-size: 14px; font-weight: bold; margin-bottom: 8px;">Observed</div>
<table style="border-collapse: collapse; font-size: 13px;">
<thead style="background: #667eea; color: white;">
<tr>
<th style="padding: 7px; border: 1px solid #ddd;"></th>
<th style="padding: 7px; border: 1px solid #ddd;">1st</th>
<th style="padding: 7px; border: 1px solid #ddd;">4th</th>
<th style="padding: 7px; border: 1px solid #ddd;">Total</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Coffee</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e3f2fd;">${cell11}</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e3f2fd;">${cell12}</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #fff3e0;">${r1}</td>
</tr>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Tea</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e3f2fd;">${cell21}</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e3f2fd;">${cell22}</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #fff3e0;">${r2}</td>
</tr>
<tr style="background: #f0f0f0;">
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Total</td>
<td style="padding: 6px; border: 1px solid #ddd;">${c1}</td>
<td style="padding: 6px; border: 1px solid #ddd;">${c2}</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #667eea; color: white;">${n}</td>
</tr>
</tbody>
</table>
</div>
<div>
<div style="font-size: 14px; font-weight: bold; margin-bottom: 8px;">Expected</div>
<table style="border-collapse: collapse; font-size: 13px;">
<thead style="background: #2ecc71; color: white;">
<tr>
<th style="padding: 7px; border: 1px solid #ddd;"></th>
<th style="padding: 7px; border: 1px solid #ddd;">1st</th>
<th style="padding: 7px; border: 1px solid #ddd;">4th</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Coffee</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">${e11.toFixed(2)}</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">${e12.toFixed(2)}</td>
</tr>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Tea</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">${e21.toFixed(2)}</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">${e22.toFixed(2)}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div style="display: flex; gap: 15px; justify-content: center;">
<div style="background: #e3f2fd; padding: 10px; border-radius: 8px; font-size: 14px;">
<strong>χ² = ${chisq2x2.toFixed(2)}</strong>
</div>
<div style="background: ${chisq2x2 > critical2x2 ? '#e8f5e9' : '#ffebee'}; padding: 10px; border-radius: 8px; font-size: 14px; border: 2px solid ${chisq2x2 > critical2x2 ? '#4caf50' : '#f44336'};">
${chisq2x2 > critical2x2 ? '✓ Dependent' : '✗ Independent'}
</div>
</div>
<div style="font-size: 13px; background: #fff9c4; padding: 10px; border-radius: 8px; margin-top: 10px;">
Expected changes because: E = (Row Total × Column Total) / Grand Total
</div>
</div>`;
}Try different table sizes:
{
const r = numRow;
const c = numCol;
const df = (r - 1) * (c - 1);
return html`
<div style="text-align: center;">
<div style="display: flex; gap: 20px; justify-content: center; margin: 15px;">
<div style="background: #e3f2fd; padding: 18px; border-radius: 10px;">
<div style="font-size: 28px; font-weight: bold; color: #1976d2; margin-bottom: 8px;">
${r} × ${c}
</div>
<div style="font-size: 15px;">
Table dimensions
</div>
</div>
<div style="background: #e8f5e9; padding: 18px; border-radius: 10px;">
<div style="font-size: 28px; font-weight: bold; color: #4caf50; margin-bottom: 8px;">
${df}
</div>
<div style="font-size: 15px;">
df = (${r}-1) × (${c}-1)
</div>
</div>
</div>
<div style="background: #fff9c4; padding: 15px; border-radius: 10px; margin-top: 15px; max-width: 700px; margin-left: auto; margin-right: auto;">
<div style="font-size: 15px; line-height: 1.6;">
<strong>Why ${df}?</strong> If row and column totals are fixed,<br/>
only ${(r-1)*(c-1)} cells are "free to vary".<br/>
The remaining cells are determined.
</div>
</div>
</div>`;
}Same χ² with different df = different conclusions:
{
const df = dfChoice2;
const chi = chiValue2;
// Critical values at p = .05
const criticals = {
1: 3.84,
2: 5.99,
3: 7.81,
4: 9.49
};
const critical = criticals[df];
const significant = chi > critical;
return html`
<div style="text-align: center;">
<div style="background: #f8f9fa; padding: 15px; border-radius: 10px; margin-bottom: 15px;">
<div style="font-size: 18px;">
<strong>Your values:</strong> χ² = ${chi.toFixed(2)}, df = ${df}
</div>
</div>
<div style="display: flex; gap: 20px; justify-content: center; margin: 20px;">
<div style="background: #e3f2fd; padding: 20px; border-radius: 10px;">
<div style="font-size: 28px; font-weight: bold; color: #1976d2; margin-bottom: 10px;">
${chi.toFixed(2)}
</div>
<div style="font-size: 16px;">
Observed χ²
</div>
</div>
<div style="background: #fff3e0; padding: 20px; border-radius: 10px;">
<div style="font-size: 28px; font-weight: bold; color: #e65100; margin-bottom: 10px;">
${critical.toFixed(2)}
</div>
<div style="font-size: 16px;">
Critical (df=${df}, p=.05)
</div>
</div>
</div>
<div style="background: ${significant ? '#e8f5e9' : '#ffebee'}; padding: 20px; border-radius: 10px; border: 3px solid ${significant ? '#4caf50' : '#f44336'};">
<div style="font-size: 22px; font-weight: bold; margin-bottom: 10px;">
${significant ? '✓ Reject H₀ (Dependent)' : '✗ Fail to reject H₀ (Independent)'}
</div>
<div style="font-size: 17px;">
${significant ?
`χ² (${chi.toFixed(2)}) > critical (${critical.toFixed(2)})` :
`χ² (${chi.toFixed(2)}) ≤ critical (${critical.toFixed(2)})`}
</div>
</div>
</div>`;
}html`<div style="padding: 12px;">
<div style="display: flex; flex-direction: column; gap: 13px; max-width: 800px; margin: 0 auto;">
<div style="background: #e8f5e9; padding: 18px; border-radius: 10px; border-left: 5px solid #4caf50;">
<div style="font-size: 18px; font-weight: bold; margin-bottom: 8px; color: #2e7d32;">
Marketing Research
</div>
<div style="font-size: 17px;">
Brand preference by age | Purchases by ad exposure
</div>
</div>
<div style="background: #e3f2fd; padding: 18px; border-radius: 10px; border-left: 5px solid #2196f3;">
<div style="font-size: 18px; font-weight: bold; margin-bottom: 8px; color: #1565c0;">
Medical Studies
</div>
<div style="font-size: 17px;">
Disease outcome by treatment | Side effects by dosage
</div>
</div>
<div style="background: #fff3e0; padding: 18px; border-radius: 10px; border-left: 5px solid #ff9800;">
<div style="font-size: 18px; font-weight: bold; margin-bottom: 8px; color: #e65100;">
Survey Analysis
</div>
<div style="font-size: 17px;">
Political preference by region | Responses by gender
</div>
</div>
<div style="background: #f3e5f5; padding: 18px; border-radius: 10px; border-left: 5px solid #9c27b0;">
<div style="font-size: 18px; font-weight: bold; margin-bottom: 8px; color: #6a1b9a;">
Quality Control
</div>
<div style="font-size: 17px;">
Defect rate vs expected | Errors by shift
</div>
</div>
</div>
</div>`Malaysia beverage preference study (n=200)
html`<div style="text-align: center;">
<div style="background: #fff9c4; padding: 15px; border-radius: 10px; margin-bottom: 15px;">
<div style="font-size: 18px; font-weight: bold;">
Does beverage preference depend on ethnicity?
</div>
</div>
<table style="margin: 0 auto; border-collapse: collapse; box-shadow: 0 2px 8px rgba(0,0,0,0.1); font-size: 16px;">
<thead style="background: #667eea; color: white;">
<tr>
<th style="padding: 10px; border: 1px solid #ddd;"></th>
<th style="padding: 10px; border: 1px solid #ddd;">Malay</th>
<th style="padding: 10px; border: 1px solid #ddd;">Chinese</th>
<th style="padding: 10px; border: 1px solid #ddd;">Indian</th>
<th style="padding: 10px; border: 1px solid #ddd;">Total</th>
</tr>
</thead>
<tbody style="background: white;">
<tr>
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Teh Tarik</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">55</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">30</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">35</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #fff3e0;">120</td>
</tr>
<tr>
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Kopi O</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">25</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">35</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">20</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #fff3e0;">80</td>
</tr>
<tr style="background: #e8f5e9;">
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Total</td>
<td style="padding: 8px; border: 1px solid #ddd;">80</td>
<td style="padding: 8px; border: 1px solid #ddd;">65</td>
<td style="padding: 8px; border: 1px solid #ddd;">55</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #667eea; color: white;">200</td>
</tr>
</tbody>
</table>
<div style="background: #e8f5e9; padding: 15px; border-radius: 10px; margin-top: 15px; border: 3px solid #4caf50;">
<div style="font-size: 19px; font-weight: bold; margin-bottom: 8px;">
χ²(2) = 8.67, p = .013
</div>
<div style="font-size: 17px;">
✓ Preference depends on ethnicity
</div>
</div>
</div>`Comparing observed vs expected values:
html`<div style="text-align: center;">
<div style="display: flex; gap: 15px; justify-content: center; margin-bottom: 15px;">
<div>
<div style="font-size: 14px; font-weight: bold; margin-bottom: 8px;">Observed</div>
<table style="border-collapse: collapse; font-size: 13px;">
<thead style="background: #667eea; color: white;">
<tr>
<th style="padding: 7px; border: 1px solid #ddd;"></th>
<th style="padding: 7px; border: 1px solid #ddd;">Malay</th>
<th style="padding: 7px; border: 1px solid #ddd;">Chinese</th>
<th style="padding: 7px; border: 1px solid #ddd;">Indian</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Teh Tarik</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #ffcdd2;">55</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #c8e6c9;">30</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #fff3e0;">35</td>
</tr>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Kopi O</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #c8e6c9;">25</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #ffcdd2;">35</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #fff3e0;">20</td>
</tr>
</tbody>
</table>
</div>
<div>
<div style="font-size: 14px; font-weight: bold; margin-bottom: 8px;">Expected</div>
<table style="border-collapse: collapse; font-size: 13px;">
<thead style="background: #2ecc71; color: white;">
<tr>
<th style="padding: 7px; border: 1px solid #ddd;"></th>
<th style="padding: 7px; border: 1px solid #ddd;">Malay</th>
<th style="padding: 7px; border: 1px solid #ddd;">Chinese</th>
<th style="padding: 7px; border: 1px solid #ddd;">Indian</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Teh Tarik</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">48</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">39</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">33</td>
</tr>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Kopi O</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">32</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">26</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">22</td>
</tr>
</tbody>
</table>
</div>
</div>
<div style="background: #fff9c4; padding: 15px; border-radius: 10px; font-size: 16px;">
<div style="text-align: left; line-height: 1.6;">
<strong>Key Findings:</strong><br/>
• <span style="background: #ffcdd2; padding: 2px 5px;">Malays:</span> Higher-than-expected Teh Tarik preference (+7)<br/>
• <span style="background: #ffcdd2; padding: 2px 5px;">Chinese:</span> Higher-than-expected Kopi O preference (+9)<br/>
• <span style="background: #c8e6c9; padding: 2px 5px;">Indians:</span> Close to expected values (balanced)
</div>
</div>
</div>`Does attendance impact final grade? (n=150)
html`<div style="text-align: center;">
<div style="background: #fff9c4; padding: 15px; border-radius: 10px; margin-bottom: 15px;">
<div style="font-size: 18px; font-weight: bold;">
Does final grade depend on attendance?
</div>
</div>
<table style="margin: 0 auto; border-collapse: collapse; box-shadow: 0 2px 8px rgba(0,0,0,0.1); font-size: 16px;">
<thead style="background: #667eea; color: white;">
<tr>
<th style="padding: 10px; border: 1px solid #ddd;"></th>
<th style="padding: 10px; border: 1px solid #ddd;">Pass (A/B)</th>
<th style="padding: 10px; border: 1px solid #ddd;">Fail (C/D/F)</th>
<th style="padding: 10px; border: 1px solid #ddd;">Total</th>
</tr>
</thead>
<tbody style="background: white;">
<tr>
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">High Attendance (>80%)</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">65</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">15</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #fff3e0;">80</td>
</tr>
<tr>
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Low Attendance (<80%)</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">30</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">40</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #fff3e0;">70</td>
</tr>
<tr style="background: #e8f5e9;">
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Total</td>
<td style="padding: 8px; border: 1px solid #ddd;">95</td>
<td style="padding: 8px; border: 1px solid #ddd;">55</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #667eea; color: white;">150</td>
</tr>
</tbody>
</table>
<div style="background: #e8f5e9; padding: 15px; border-radius: 10px; margin-top: 15px; border: 3px solid #4caf50;">
<div style="font-size: 19px; font-weight: bold; margin-bottom: 8px;">
χ²(1) = 24.15, p < .001
</div>
<div style="font-size: 17px;">
✓ Strong relationship: Attendance matters!
</div>
</div>
</div>`Comparing observed vs expected values:
html`<div style="text-align: center;">
<div style="display: flex; gap: 15px; justify-content: center; margin-bottom: 15px;">
<div>
<div style="font-size: 14px; font-weight: bold; margin-bottom: 8px;">Observed</div>
<table style="border-collapse: collapse; font-size: 13px;">
<thead style="background: #667eea; color: white;">
<tr>
<th style="padding: 7px; border: 1px solid #ddd;"></th>
<th style="padding: 7px; border: 1px solid #ddd;">Pass</th>
<th style="padding: 7px; border: 1px solid #ddd;">Fail</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">High (>80%)</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #ffcdd2;">65</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #c8e6c9;">15</td>
</tr>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Low (<80%)</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #c8e6c9;">30</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #ffcdd2;">40</td>
</tr>
</tbody>
</table>
</div>
<div>
<div style="font-size: 14px; font-weight: bold; margin-bottom: 8px;">Expected</div>
<table style="border-collapse: collapse; font-size: 13px;">
<thead style="background: #2ecc71; color: white;">
<tr>
<th style="padding: 7px; border: 1px solid #ddd;"></th>
<th style="padding: 7px; border: 1px solid #ddd;">Pass</th>
<th style="padding: 7px; border: 1px solid #ddd;">Fail</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">High (>80%)</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">50.67</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">29.33</td>
</tr>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Low (<80%)</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">44.33</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">25.67</td>
</tr>
</tbody>
</table>
</div>
</div>
<div style="background: #fff9c4; padding: 15px; border-radius: 10px; font-size: 16px;">
<div style="text-align: left; line-height: 1.6;">
<strong>Key Findings:</strong><br/>
• <span style="background: #ffcdd2; padding: 2px 5px;">High attendance:</span> Pass rate 14 points higher than expected<br/>
• <span style="background: #ffcdd2; padding: 2px 5px;">Low attendance:</span> Fail rate 14 points higher than expected<br/>
• <span style="background: #c8e6c9; padding: 2px 5px;">Very strong effect:</span> Attendance strongly predicts performance
</div>
</div>
</div>`Platform preference by age group (n=300)
html`<div style="text-align: center;">
<div style="background: #fff9c4; padding: 15px; border-radius: 10px; margin-bottom: 15px;">
<div style="font-size: 18px; font-weight: bold;">
Does platform preference depend on age?
</div>
</div>
<table style="margin: 0 auto; border-collapse: collapse; box-shadow: 0 2px 8px rgba(0,0,0,0.1); font-size: 16px;">
<thead style="background: #667eea; color: white;">
<tr>
<th style="padding: 10px; border: 1px solid #ddd;"></th>
<th style="padding: 10px; border: 1px solid #ddd;">18-25</th>
<th style="padding: 10px; border: 1px solid #ddd;">26-40</th>
<th style="padding: 10px; border: 1px solid #ddd;">41+</th>
<th style="padding: 10px; border: 1px solid #ddd;">Total</th>
</tr>
</thead>
<tbody style="background: white;">
<tr>
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">TikTok</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">70</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">25</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">5</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #fff3e0;">100</td>
</tr>
<tr>
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Instagram</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">55</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">60</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">35</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #fff3e0;">150</td>
</tr>
<tr>
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Facebook</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">5</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">15</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #e3f2fd;">30</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #fff3e0;">50</td>
</tr>
<tr style="background: #e8f5e9;">
<td style="padding: 8px; border: 1px solid #ddd; font-weight: bold;">Total</td>
<td style="padding: 8px; border: 1px solid #ddd;">130</td>
<td style="padding: 8px; border: 1px solid #ddd;">100</td>
<td style="padding: 8px; border: 1px solid #ddd;">70</td>
<td style="padding: 8px; border: 1px solid #ddd; background: #667eea; color: white;">300</td>
</tr>
</tbody>
</table>
<div style="background: #e8f5e9; padding: 15px; border-radius: 10px; margin-top: 15px; border: 3px solid #4caf50;">
<div style="font-size: 19px; font-weight: bold; margin-bottom: 8px;">
χ²(4) = 62.41, p < .001
</div>
<div style="font-size: 17px;">
✓ Clear age-based platform preferences
</div>
</div>
</div>`Comparing observed vs expected values:
html`<div style="text-align: center;">
<div style="display: flex; gap: 15px; justify-content: center; margin-bottom: 15px;">
<div>
<div style="font-size: 14px; font-weight: bold; margin-bottom: 8px;">Observed</div>
<table style="border-collapse: collapse; font-size: 13px;">
<thead style="background: #667eea; color: white;">
<tr>
<th style="padding: 7px; border: 1px solid #ddd;"></th>
<th style="padding: 7px; border: 1px solid #ddd;">18-25</th>
<th style="padding: 7px; border: 1px solid #ddd;">26-40</th>
<th style="padding: 7px; border: 1px solid #ddd;">41+</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">TikTok</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #ffcdd2;">70</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #c8e6c9;">25</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #c8e6c9;">5</td>
</tr>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Instagram</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #fff3e0;">55</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #ffcdd2;">60</td>
<td style="padding: 6px; border: 1px solid #ddd;">35</td>
</tr>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Facebook</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #c8e6c9;">5</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #c8e6c9;">15</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #ffcdd2;">30</td>
</tr>
</tbody>
</table>
</div>
<div>
<div style="font-size: 14px; font-weight: bold; margin-bottom: 8px;">Expected</div>
<table style="border-collapse: collapse; font-size: 13px;">
<thead style="background: #2ecc71; color: white;">
<tr>
<th style="padding: 7px; border: 1px solid #ddd;"></th>
<th style="padding: 7px; border: 1px solid #ddd;">18-25</th>
<th style="padding: 7px; border: 1px solid #ddd;">26-40</th>
<th style="padding: 7px; border: 1px solid #ddd;">41+</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">TikTok</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">43.3</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">33.3</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">23.3</td>
</tr>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Instagram</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">65</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">50</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">35</td>
</tr>
<tr>
<td style="padding: 6px; border: 1px solid #ddd; font-weight: bold;">Facebook</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">21.7</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">16.7</td>
<td style="padding: 6px; border: 1px solid #ddd; background: #e8f5e9;">11.7</td>
</tr>
</tbody>
</table>
</div>
</div>
<div style="background: #fff9c4; padding: 15px; border-radius: 10px; font-size: 16px;">
<div style="text-align: left; line-height: 1.6;">
<strong>Key Findings:</strong><br/>
• <span style="background: #ffcdd2; padding: 2px 5px;">18-25:</span> TikTok 27 points higher than expected<br/>
• <span style="background: #ffcdd2; padding: 2px 5px;">26-40:</span> Instagram 10 points higher than expected<br/>
• <span style="background: #ffcdd2; padding: 2px 5px;">41+:</span> Facebook 18 points higher than expected<br/>
• Clear age-stratified platform preferences
</div>
</div>
</div>`html`<div style="padding: 15px;">
<div style="background: #fff9c4; padding: 15px; border-radius: 10px; margin-bottom: 12px; text-align: center; font-size: 18px;">
<strong>Is your DV categorical?</strong>
</div>
<div style="display: flex; gap: 12px; justify-content: center;">
<div style="flex: 1; max-width: 300px;">
<div style="background: #ffebee; padding: 12px; border-radius: 10px; text-align: center; font-size: 16px;">
<strong>NO</strong><br/>(continuous)<br/>
↓<br/>
t-test, ANOVA,<br/>regression
</div>
</div>
<div style="flex: 1; max-width: 350px;">
<div style="background: #e8f5e9; padding: 12px; border-radius: 10px; text-align: center; font-size: 16px; margin-bottom: 10px;">
<strong>YES</strong><br/>(categories)<br/>
↓<br/>
How many variables?
</div>
<div style="display: flex; flex-direction: column; gap: 10px;">
<div style="background: #e3f2fd; padding: 10px; border-radius: 10px; text-align: center; font-size: 15px;">
<strong>ONE</strong><br/>
Goodness of Fit
</div>
<div style="background: #f3e5f5; padding: 10px; border-radius: 10px; text-align: center; font-size: 15px;">
<strong>TWO+</strong><br/>
Independence
</div>
</div>
</div>
</div>
</div>`html`<div style="padding: 15px;">
<div style="background: #e8f5e9; padding: 18px; border-radius: 10px; margin-bottom: 12px;">
<div style="font-size: 19px; font-weight: bold; margin-bottom: 10px; color: #2e7d32;">
Chi-Square Statistic:
</div>
<div style="font-size: 26px; text-align: center; background: white; padding: 12px; border-radius: 8px;">
χ² = Σ [(O - E)² / E]
</div>
</div>
<div style="background: #e3f2fd; padding: 18px; border-radius: 10px;">
<div style="font-size: 19px; font-weight: bold; margin-bottom: 10px; color: #1565c0;">
Expected Frequency:
</div>
<div style="font-size: 26px; text-align: center; background: white; padding: 12px; border-radius: 8px;">
E = (Row × Column) / Grand Total
</div>
</div>
</div>`html`<div style="padding: 15px;">
<div style="display: flex; flex-direction: column; gap: 12px;">
<div style="background: #e3f2fd; padding: 15px; border-radius: 10px; border-left: 5px solid #2196f3;">
<div style="font-size: 17px; font-weight: bold; margin-bottom: 8px; color: #1565c0;">
✓ Calculate Expected Values
</div>
<div style="font-size: 15px;">
Use the formula (Row Total × Column Total) / Grand Total for each cell. Check totals sum correctly.
</div>
</div>
<div style="background: #fff3e0; padding: 15px; border-radius: 10px; border-left: 5px solid #ff9800;">
<div style="font-size: 17px; font-weight: bold; margin-bottom: 8px; color: #e65100;">
✓ Identify Correct df
</div>
<div style="font-size: 15px;">
Goodness of Fit: df = k - 1 | Independence: df = (r-1) × (c-1). Always check your table dimensions!
</div>
</div>
<div style="background: #e8f5e9; padding: 15px; border-radius: 10px; border-left: 5px solid #4caf50;">
<div style="font-size: 17px; font-weight: bold; margin-bottom: 8px; color: #2e7d32;">
✓ Interpret p-values Correctly
</div>
<div style="font-size: 15px;">
<strong>Goodness of Fit:</strong> p < .05 → Reject H₀ (data differs from expected distribution)<br/>
<strong>Independence:</strong> p < .05 → Reject H₀ (variables ARE related/dependent)
</div>
</div>
<div style="background: #f3e5f5; padding: 15px; border-radius: 10px; border-left: 5px solid #9c27b0;">
<div style="font-size: 17px; font-weight: bold; margin-bottom: 8px; color: #6a1b9a;">
✓ Choose the Right Test
</div>
<div style="font-size: 15px;">
ONE categorical variable → Goodness of Fit | TWO+ categorical variables → Independence
</div>
</div>
<div style="background: #ffebee; padding: 15px; border-radius: 10px; border-left: 5px solid #f44336;">
<div style="font-size: 17px; font-weight: bold; margin-bottom: 8px; color: #c62828;">
✗ Don't Confuse with Continuous Tests
</div>
<div style="font-size: 15px;">
Chi-square is ONLY for categorical data. Use t-test/ANOVA for continuous outcomes (amounts, scores, times).
</div>
</div>
</div>
</div>`