CATrend Analyzer
Cochran–Armitage Trend Test · v1.0.0
Source Code
Statistical Analysis Software

Cochran–Armitage
Trend Test, reimagined.

A free, open-source web tool for analysing trends in proportions across ordered categorical groups — built for clinical trials, epidemiology, and public health research.

100%
Free & Open Source
No Login
Required
1 & 2‑sided
P-value Reporting
Word / CSV
Export Formats
Sample Trend Analysis
Increasing success rates across treatment levels
DEMO
Frequency by group
Sample contingency table
4.32
Z-statistic (signed)
<0.001
Two-sided P-value
Increasing
Trend direction
400
Total observations
About the Cochran–Armitage Trend Test

The Cochran–Armitage Trend Test (CATT) is a statistical method for detecting monotone trends in proportions across ordered categorical variables. It is especially powerful when the explanatory variable has a natural ordering and the outcome is binary.

  • Clinical Trials: Testing if treatment response increases with dosage levels
  • Epidemiology: Analysing disease incidence across ordered age groups
  • Public Health: Examining vaccination rates across socioeconomic strata
  • Genetics: Testing genotype–phenotype associations (dose-response modelling)
  • Market Research: Analysing preference trends across product variants
Z = Σ yⱼ(xⱼ − x̄) / √[ p̄(1−p̄) · Σ nⱼ(xⱼ − x̄)² ]

Key assumptions: ordered categories, independent observations, binary outcome, sufficient sample size for normal approximation, non-zero marginal totals.

Key Features
Interactive Contingency Tables
Create and edit tables with unlimited rows and columns. Dynamic totals update in real time as you type.
Stacked Bar Visualisation
Stacked bar charts with counts, row %, and column % labels — consistent with epidemiological standards. Full-screen view and PNG export.
Professional Export
Export to Microsoft Word with complete tables, results, interpretation, and APA citation. Also exports to CSV formats.
Automatic Interpretation
Signed Z-statistic, one-sided & two-sided p-values, trend direction, and plain-language summaries.
Educational Resources
Detailed formula explanations, step-by-step documentation, and a comprehensive FAQ section.
Custom Bar Colors
Choose your own colors for each bar series in the stacked chart. Reset to defaults with one click.

Cochran–Armitage Trend Test

Enter your contingency table, configure options, and run the analysis. Results with full interpretation appear below.

Contingency Table Input
Enter frequency counts (whole numbers). Row 1 = success/event; Columns = ordered groups. Click any header to rename it.
Rows
Columns
Analysis Options
Z = Σ yⱼ(xⱼ − x̄) / √[p̄(1−p̄) Σ nⱼ(xⱼ − x̄)²]
Chart Labels
Please enter valid numeric data before running the analysis.

Documentation

Statistical methodology, interpretation guidelines, and answers to frequently asked questions.

Mathematical Foundation

The test statistic is computed as:

Z = (Σ yⱼ(xⱼ − x̄)) / √[ p̄(1−p̄) · Σ nⱼ(xⱼ − x̄)² ]
  • xⱼ — Scores for ordered groups (default: 1, 2, 3, …)
  • yⱼ — Success counts in each group
  • nⱼ — Total counts in each group
  • — Weighted mean: Σ(nⱼ·xⱼ)/N
  • — Overall proportion of successes: Σyⱼ/N
  • N — Grand total: Σnⱼ

Signed Z-statistic: CATrend Analyzer reports a signed Z value. A positive Z indicates an increasing trend; a negative Z indicates a decreasing trend. Both one-sided and two-sided p-values are reported.

Continuity correction:

Z = (|Σ yⱼ(xⱼ − x̄)| − 0.5) / √[ p̄(1−p̄) · Σ nⱼ(xⱼ − x̄)² ]

P-value computation:

One-sided p-value = 1 − Φ(|Z|) [tail in direction of observed Z] Two-sided p-value = 2 × (1 − Φ(|Z|)) Chi-square (Pearson, general association): Expected Eᵢⱼ = (rowTotalᵢ × colTotalⱼ) / N χ² = Σᵢⱼ (Oᵢⱼ − Eᵢⱼ)² / Eᵢⱼ df = (rows−1) × (cols−1)

Step-by-step algorithm:

1. Assign scores xⱼ = 1, 2, …, k 2. Compute column totals nⱼ and success counts yⱼ 3. Compute weighted mean x̄ = Σ(nⱼ·xⱼ) / N 4. Compute overall proportion p̄ = Σyⱼ / N 5. Numerator = Σ yⱼ(xⱼ − x̄) 6. Variance = p̄(1−p̄) · Σ nⱼ(xⱼ − x̄)² 7. Z = (|Numerator| − correction) / √Variance, sign from Numerator 8. One-sided p = 1 − Φ(|Z|) 9. Two-sided p = 2 × (1 − Φ(|Z|))
Interpretation Guidelines
  • p < 0.001 — Highly significant trend
  • p < 0.01 — Very significant trend
  • p < 0.05 — Statistically significant trend
  • p ≥ 0.05 — No significant trend detected
Frequently Asked Questions
What is the minimum sample size required?
There is no strict minimum. The test relies on a normal approximation, so it works best when expected counts per cell are not too small. A common guideline is ≥ 20 observations per group. For smaller samples, consider exact methods.
Can I use this test for more than two outcome categories?
No. CATT requires a binary outcome. For ordinal outcomes with multiple categories, consider the Jonckheere–Terpstra test or the linear-by-linear association test.
What is the difference between one-sided and two-sided p-values?
The one-sided p-value tests whether the trend goes in a specific direction (increasing or decreasing) as observed. The two-sided p-value tests whether any trend exists regardless of direction. For confirmatory analysis where you pre-specified the direction, the one-sided p is appropriate; otherwise, the two-sided p is recommended.
How does this differ from a chi-square test?
The Pearson chi-square test detects any association between variables (df = (rows−1)×(cols−1)). CATT specifically tests for a linear trend in proportions across ordered groups (df = 1), making it more powerful when a monotone trend is expected. The chi-square results shown here use the correct Pearson formula compatible with SPSS, R, and SAS.
How do I cite CATrend Analyzer?
Use the citation provided in the results panel after running an analysis. The citation follows APA format and includes the retrieval URL.
Why is a stacked bar chart used instead of grouped bars?
Stacked bar charts are the epidemiological and public health standard for displaying proportional composition across ordered groups. They make it visually intuitive to see how the proportion of each outcome (success vs. failure) changes across groups — which is precisely what CATT tests.
Troubleshooting
Zero cells: The test may still run, but interpret results cautiously. Consider aggregating groups or using exact methods.
Small samples (N < 20): Normal approximation may be invalid. Enable continuity correction or consult a statistician.
Missing data: All cells must be filled with non-negative integers. Handle missing data before entering values.

Developer

About the creator of CATrend Analyzer and the technical implementation.

About the Developer
👨‍💻
Mudasir Mohammed Ibrahim
Registered Nurse & Health Researcher · Ghana
A dedicated healthcare professional with a passion for data analysis and research methodology. CATrend Analyzer was created to bridge the gap between clinical practice and statistical analysis — making advanced tools accessible to healthcare professionals, researchers, and students without requiring programming knowledge.
Healthcare Vision
Improve outcomes through accessible data analysis tools that empower medical professionals to make evidence-based decisions.
Technical Approach
Developing user-friendly, open-source tools implementing rigorous statistical methods with clinical relevance.
Community Impact
Free resources supporting healthcare research and education worldwide, particularly in resource-limited settings.
Technology Stack
HTML5
Semantic markup & SEO
CSS3
Custom properties, Grid
JavaScript
Vanilla ES6+
Chart.js
Data visualisation

All statistical computations run entirely client-side. No data is transmitted to any server.

// Core Cochran–Armitage computation function performCATT(data, cc) { const scores = data.cols.map((_,i) => i + 1); const N = data.flat().reduce((a,b) => a+b, 0); const nj = scores.map((_,j) => data.reduce((s,r) => s+r[j], 0)); const yj = data[0]; const xbar = nj.reduce((s,n,j) => s + n*scores[j], 0) / N; const pbar = yj.reduce((a,b) => a+b, 0) / N; const num = yj.reduce((s,y,j) => s + y*(scores[j]-xbar), 0); const den = Math.sqrt(pbar*(1-pbar)*nj.reduce((s,n,j) => s + n*(scores[j]-xbar)**2, 0)); const Z = (Math.abs(num)-(cc?0.5:0))/den * Math.sign(num); return { Z, pOne: 1-normalCDF(Math.abs(Z)), pTwo: 2*(1-normalCDF(Math.abs(Z))) }; }