Type-safe data analytics and statistics in TypeScript. Research shows that static typing can prevent 15–38% of production bugs1,2,3. Designed for modern data science workflows.
Create, transform, filter, select, and sort data with chaining and automatic column typing for compile-time safety.
Learn More80+ functions across descriptive statistics, hypothesis testing, and probability distributions. All tests are rigorously validated against results from R.
Learn MoreA complete data analysis workflow, broken into focused examples
import { createDataFrame } from "@tidy-ts/dataframe";
// 🚀 Load character data from the galaxy
const characters = createDataFrame([
{ name: "Luke", species: "Human", mass_kg: 77, height_cm: 172 },
{ name: "Leia", species: "Human", mass_kg: 49, height_cm: 150 },
{ name: "C-3PO", species: "Droid", mass_kg: 75, height_cm: 167 },
{ name: "R2-D2", species: "Droid", mass_kg: 32, height_cm: 96 },
]);
characters.print();
// Output:
// ┌───────┬────────┬─────────┬───────────┐
// │ name │ species│ mass_kg │ height_cm │
// ├───────┼────────┼─────────┼───────────┤
// │ Luke │ Human │ 77 │ 172 │
// │ Leia │ Human │ 49 │ 150 │
// │ C-3PO │ Droid │ 75 │ 167 │
// │ R2-D2 │ Droid │ 32 │ 96 │
// └───────┴────────┴─────────┴───────────┘
import { createDataFrame } from "@tidy-ts/dataframe";
// 🚀 Load character data from the galaxy
const characters = createDataFrame([
{ name: "Luke", species: "Human", mass_kg: 77, height_cm: 172 },
{ name: "Leia", species: "Human", mass_kg: 49, height_cm: 150 },
{ name: "C-3PO", species: "Droid", mass_kg: 75, height_cm: 167 },
{ name: "R2-D2", species: "Droid", mass_kg: 32, height_cm: 96 },
]);
characters.print();
// Output:
// ┌───────┬────────┬─────────┬───────────┐
// │ name │ species│ mass_kg │ height_cm │
// ├───────┼────────┼─────────┼───────────┤
// │ Luke │ Human │ 77 │ 172 │
// │ Leia │ Human │ 49 │ 150 │
// │ C-3PO │ Droid │ 75 │ 167 │
// │ R2-D2 │ Droid │ 32 │ 96 │
// └───────┴────────┴─────────┴───────────┘
// 🔧 Transform data with calculated columns
const analysis = characters
.mutate({
mass_lbs: (row) => row.mass_kg * 2.20462, // Convert to pounds
height_in: (row) => row.height_cm / 2.54, // Convert to inches
bmi: (row) => row.mass_kg / ((row.height_cm / 100) ** 2), // Body Mass Index
})
.select("name", "mass_lbs", "height_in", "bmi");
analysis.print("Character Analysis with Calculations");
// Output:
// Character Analysis with Calculations
// ┌───────┬──────────┬───────────┬─────────┐
// │ name │ mass_lbs │ height_in │ bmi │
// ├───────┼──────────┼───────────┼─────────┤
// │ Luke │ 169.76 │ 67.72 │ 26.03 │
// │ Leia │ 108.03 │ 59.06 │ 21.78 │
// │ C-3PO │ 165.35 │ 65.75 │ 26.89 │
// │ R2-D2 │ 70.55 │ 37.80 │ 34.72 │
// └───────┴──────────┴───────────┴─────────┘
// 🔧 Transform data with calculated columns
const analysis = characters
.mutate({
mass_lbs: (row) => row.mass_kg * 2.20462, // Convert to pounds
height_in: (row) => row.height_cm / 2.54, // Convert to inches
bmi: (row) => row.mass_kg / ((row.height_cm / 100) ** 2), // Body Mass Index
})
.select("name", "mass_lbs", "height_in", "bmi");
analysis.print("Character Analysis with Calculations");
// Output:
// Character Analysis with Calculations
// ┌───────┬──────────┬───────────┬─────────┐
// │ name │ mass_lbs │ height_in │ bmi │
// ├───────┼──────────┼───────────┼─────────┤
// │ Luke │ 169.76 │ 67.72 │ 26.03 │
// │ Leia │ 108.03 │ 59.06 │ 21.78 │
// │ C-3PO │ 165.35 │ 65.75 │ 26.89 │
// │ R2-D2 │ 70.55 │ 37.80 │ 34.72 │
// └───────┴──────────┴───────────┴─────────┘
import { stats as s } from "@tidy-ts/dataframe";
// 📊 Group by species and calculate statistics
const summary = analysis
.groupBy("species")
.summarize({
avg_mass_lbs: (group) => s.mean(group.mass_lbs),
avg_height_in: (group) => s.mean(group.height_in),
count: (group) => group.nrows(),
})
.arrange("avg_mass_lbs", "desc");
summary.print("Species Comparison Report");
// Output:
// Species Comparison Report
// ┌────────┬───────────────┬───────────────┬───────┐
// │ species│ avg_mass_lbs │ avg_height_in │ count │
// ├────────┼───────────────┼───────────────┼───────┤
// │ Human │ 138.90 │ 63.39 │ 2 │
// │ Droid │ 117.95 │ 51.78 │ 2 │
// └────────┴───────────────┴───────────────┴───────┘
import { stats as s } from "@tidy-ts/dataframe";
// 📊 Group by species and calculate statistics
const summary = analysis
.groupBy("species")
.summarize({
avg_mass_lbs: (group) => s.mean(group.mass_lbs),
avg_height_in: (group) => s.mean(group.height_in),
count: (group) => group.nrows(),
})
.arrange("avg_mass_lbs", "desc");
summary.print("Species Comparison Report");
// Output:
// Species Comparison Report
// ┌────────┬───────────────┬───────────────┬───────┐
// │ species│ avg_mass_lbs │ avg_height_in │ count │
// ├────────┼───────────────┼───────────────┼───────┤
// │ Human │ 138.90 │ 63.39 │ 2 │
// │ Droid │ 117.95 │ 51.78 │ 2 │
// └────────┴───────────────┴───────────────┴───────┘
// Test 1: Are droid proportions (suspiciously?) similar to human proportions?
const humans = analysis.filter((r) => r.species === "Human");
const droids = analysis.filter((r) => r.species === "Droid");
const bmiTest = s.compare.twoGroups.centralTendency.toEachOther({
x: humans.bmi,
y: droids.bmi,
parametric: "auto", // Auto-detects appropriate test
});
console.log(`Droid conspiracy? Test: ${bmiTest.test_name}, p-value: ${s.round(bmiTest.p_value, 3)}`);
// Output:
// Droid conspiracy? Test: Independent T-Test, p-value: 0.261
// Test 2: Are height and mass correlated among all characters?
const heightMassTest = s.compare.twoGroups.association.toEachOther({
x: analysis.height_cm,
y: analysis.mass_kg,
method: "auto", // Selects best choice between Pearson, Spearman, or Kendall
});
console.log(`Height and mass correlation?
Test: ${heightMassTest.test_name}
${heightMassTest.effect_size.name}: ${s.round(heightMassTest.effect_size.value, 3)}
p-value: ${s.round(heightMassTest.p_value, 3)}`);
// Output:
// Height and mass correlation?
// Test: Kendall's rank correlation tau
// Kendall's Tau: 1
// p-value: 0.083
// Test 1: Are droid proportions (suspiciously?) similar to human proportions?
const humans = analysis.filter((r) => r.species === "Human");
const droids = analysis.filter((r) => r.species === "Droid");
const bmiTest = s.compare.twoGroups.centralTendency.toEachOther({
x: humans.bmi,
y: droids.bmi,
parametric: "auto", // Auto-detects appropriate test
});
console.log(`Droid conspiracy? Test: ${bmiTest.test_name}, p-value: ${s.round(bmiTest.p_value, 3)}`);
// Output:
// Droid conspiracy? Test: Independent T-Test, p-value: 0.261
// Test 2: Are height and mass correlated among all characters?
const heightMassTest = s.compare.twoGroups.association.toEachOther({
x: analysis.height_cm,
y: analysis.mass_kg,
method: "auto", // Selects best choice between Pearson, Spearman, or Kendall
});
console.log(`Height and mass correlation?
Test: ${heightMassTest.test_name}
${heightMassTest.effect_size.name}: ${s.round(heightMassTest.effect_size.value, 3)}
p-value: ${s.round(heightMassTest.p_value, 3)}`);
// Output:
// Height and mass correlation?
// Test: Kendall's rank correlation tau
// Kendall's Tau: 1
// p-value: 0.083
Empirical research shows that static typing significantly reduces production bugs
Evidence suggests that static typing prevents 15-38% of bugs that would otherwise reach production. These are conservative estimates focusing on publicly visible, type-related defects.
Note: These figures represent lower bounds, excluding pre-commit logic issues and data validation bugs.