Guided Statistics

Start with a question, see what the data can support, and keep the evidence visible. These 39 tools explain their clues instead of silently choosing an analysis for you.

One variable

Use stat.explore to see centre, spread, shape, missing values, and observations worth reviewing.

A whole table

Use stat.scan to find data-quality, design, and association clues before fitting a model.

Choosing a method

Use stat.decision_map to connect the scientific question and experimental unit to possible approaches.

A safe first pass

Import the statistics package as stat. The public functions below are readable wrappers around runtime builtins. They return ordinary records, so you can inspect the numbers and explanations rather than accepting a hidden decision.

import "statistics" as stat

let values = [12.1, 12.4, 12.8, 13.0, 13.2, 13.5, 29.0]
let result = stat.explore(values, {name: "protein concentration"})

println(stat.explain(result))
println(stat.distribution_ascii(values))
result.review_flags

The examples on this page are copyable package examples. The raw stats_* names shown in the tables are implementation-level builtins; application code should normally use stat.*.

What the guidance does not do

It does not prove normality, independence, causation, randomization, or a missing-data mechanism. It never deletes observations, transforms values, or selects a model automatically. Treat every recommendation as a prompt to check against how the data were collected.

1. Understand one numeric variable

Begin here when you have one measurement such as expression, concentration, age, or read depth.

Public functionRuntime builtinUse it to…
stat.explore(values, options?)stats_exploreSummarize centre, spread, shape, missingness, and review flags.
stat.means(values, options?)stats_meansCompare arithmetic, geometric, harmonic, trimmed, RMS, median, and mode with compatible spread choices.
stat.shape(values, options?)stats_shapeInspect skewness, kurtosis, peaks, and normal Q-Q alignment without declaring a diagnosis.
stat.distribution_clues(values, options?)stats_distribution_cluesCompare compatible normal, log-normal, Poisson, and negative-binomial clues using likelihood and AIC.
stat.uncertainty(values, options?)stats_uncertaintyCompute seeded bootstrap intervals for summaries, differences, or correlations.
stat.preview_transform(values, method, options?)stats_transform_previewCompare before and after log, log1p, square-root, z-score, robust, or min-max transformation.
stat.preprocessing(values, options?)stats_preprocessFind observable data-quality issues and see non-applied preprocessing alternatives.
stat.distribution_plot(values, options?)stats_distribution_plotDraw observations, histogram, mean, median, IQR, SD bands, and outlier flags.
stat.distribution_ascii(values, options?)stats_distribution_asciiShow the same distribution clues in a terminal-safe chart.
stat.normal_qq_plot(values, options?)stats_normal_qq_plotCompare ordered values with normal-distribution quantiles in SVG or ASCII.

Centre and spread belong together

When values behave like…Useful centreUseful spread
Roughly symmetric, additive measurementsArithmetic meanSD
Skewed or heavy-tailed measurementsMedianIQR or MAD
Positive multiplicative changesGeometric meanGeometric SD or fold interval
Rates with a common numeratorHarmonic meanReport the individual rates and design context
Category frequencyModeCounts or proportions

Variance is the average squared distance from the mean; SD is its square root and is in the original unit. Neither is “left” or “right.” On a symmetric bell-shaped distribution, mean ± 1, 2, and 3 SD are useful visual landmarks. They are not universal outlier rules for skewed data.

2. Audit a whole table and its design

Public functionRuntime builtinUse it to…
stat.profile(data, options?)stats_profileInspect types, summaries, missingness, duplicates, ranges, and declared design roles.
stat.scan(data, options?)stats_scanRun a bounded first pass with prioritized, evidence-linked next steps.
stat.overview_ascii(data, options?)stats_overview_asciiRead a compact whole-table overview in the CLI.
stat.missingness(data, options?)stats_missingnessInspect missing values by row, column, pair, and optional group.
stat.missingness_plot(data, options?)stats_missingness_plotVisualize missingness in SVG or ASCII.
stat.design_check(data, options?)stats_design_checkReview repeated units, imbalance, duplicate subject/time rows, and batch/group confounding clues.
stat.associations(data, options?)stats_associationsScreen bounded numeric and categorical effect-size associations.
stat.report(data, options?)stats_reportCreate a self-contained HTML or Markdown data-health report with provenance.
stat.guide(report, context?)stats_guideAdd the scientific question and experimental-unit context to a report.
stat.explain(report, detail?)stats_explainRender quick, learning, or audit-level plain text.
stat.decision_map(options?)stats_decision_mapBrowse question-led analysis alternatives without automatic selection.
let audit = stat.scan(data, {
  subject_column: "patient_id",
  group_column: "treatment",
  batch_column: "sequencing_batch"
})

println(stat.overview_ascii(data))
println(stat.explain(audit))
audit.recommendations

Column roles are declared by you; BioLang does not infer experimental units or randomization from convenient column names. Missingness patterns are investigation clues, not proof that data are MCAR, MAR, or MNAR.

3. Compare groups, relationships, and categories

Public functionRuntime builtinUse it to…
stat.compare(values, groups, options?)stats_compareCompare per-group evidence and see compatible analysis alternatives.
stat.relationship(x, y, options?)stats_relationshipInspect complete pairs, Pearson/Spearman association, and a regression line.
stat.categorical(values, options?)stats_categoriesCount levels, proportions, modes, missingness, and rare-level clues.
stat.group_plot(values, groups, options?)stats_group_plotDraw group observations and robust summaries in SVG or ASCII.
stat.relationship_plot(x, y, options?)stats_relationship_plotDraw a scatterplot and fitted line in SVG or ASCII.
stat.categorical_plot(values, options?)stats_categorical_plotDraw frequency bars in SVG or ASCII.

Correlation describes association, not causation. A small p-value does not tell you whether an effect is important, whether groups were independent, or whether the study design was unbiased.

4. Omics and dependent data

Public functionRuntime builtinUse it to…
stat.normalization_guide(matrix, options?)stats_normalization_guideAudit a dense or sparse matrix and see domain-aware normalization alternatives.
stat.omics_profile(matrix, options?)stats_omics_profileProfile bulk RNA-seq, single-cell, proteomics, metabolomics, microbiome, or generic matrices without densifying sparse input.
stat.weighted_summary(values, weights, options?)stats_weighted_summaryInspect weighted centre/spread, effective sample size, and weight concentration.
stat.time_series_diagnostics(values, options?)stats_time_series_diagnosticsInspect trend, autocorrelation, Ljung-Box, and first differences in an ordered regular series.
stat.cluster_diagnostics(values, clusters, options?)stats_cluster_diagnosticsEstimate one-way ICC, cluster-size imbalance, and approximate information loss.

5. Check fitted models

Public functionRuntime builtinUse it to…
stat.linear_diagnostics(x, y, options?)stats_linear_diagnosticsInspect residual form, spread, Q-Q, order, and influence for a simple linear model.
stat.linear_diagnostic_plot(x, y, options?)stats_linear_diagnostic_plotDraw residual-versus-fitted or residual Q-Q diagnostics.
stat.multiple_linear_diagnostics(predictors, outcome, options?)stats_multiple_linear_diagnosticsCheck encodings, interactions, VIF, influence, intervals, and held-out error.
stat.robust_linear_diagnostics(predictors, outcome, options?)stats_robust_linear_diagnosticsCompare Huber and ordinary least-squares coefficients as a sensitivity analysis.
stat.glm_diagnostics(predictors, outcome, options?)stats_glm_diagnosticsDiagnose binomial or Poisson fits, including convergence, dispersion, influence, and calibration or zero-count clues.
stat.random_intercept_model(predictors, outcome, clusters, options?)stats_random_intercept_modelFit fixed effects plus one declared random intercept and report pooling and variance components.
stat.cox_diagnostics(time, event, predictors, options?)stats_cox_diagnosticsFit a Cox model and inspect intervals, likelihood, baseline hazard, concordance, and residual clues.

Model checks that matter

  • Check converged before interpreting a GLM. A non-converged logistic fit can still return misleading coefficients.
  • random_intercept_model does not fit random slopes, nested effects, or crossed effects.
  • The Cox Schoenfeld screen is descriptive; it is not a formal replacement for cox.zph.
  • Diagnostics can reveal tension with a model, but cannot repair a weak study design.

Raw builtins versus the public API

The runtime performs deterministic full-data calculations under the stats_* names. The package wrappers keep user code short and stable. For example, stat.explore calls stats_explore, and stat.glm_diagnostics calls stats_glm_diagnostics. Use the raw name only when developing or testing the runtime itself.

Where to go next

  • Use Math & Statistics for direct summaries, hypothesis tests, probability functions, and mathematical operations.
  • Use the Practical Biostatistics book for visual, concept-first learning.
  • Keep the returned record with your analysis so the evidence, options, backend, and limitations remain auditable.