library(rstatix)
data("renalstone", package = "datarium")
xtab <- xtabs(~ stone + age, data = renalstone)
xtab age
stone 30-39 40-49 50-59
yes 384 536 335
no 951 869 438
Test whether a binomial proportion increases or decreases across an ordered exposure — the chi-square test for trend, more powerful than a plain chi-square
Learn to run the Cochran-Armitage trend test in R — test whether a yes/no proportion changes linearly across the ordered levels of an exposure (dose, age group, severity). Run it with rstatix prop_trend_test() on a 2×k contingency table, and see why it is more powerful than a plain chi-square when the categories are ordered.
June 23, 2026
July 7, 2026
rstatix::prop_trend_test() on a 2 × k contingency table (two outcome rows, k ordered columns).When one categorical variable is ordered — dose levels, age bands, disease stages — and the other is a yes/no outcome, you often care about a specific question: does the proportion of “yes” rise or fall as the exposure increases? A plain chi-square test only asks whether the proportions differ at all, ignoring the order. The Cochran-Armitage trend test uses the ordering, testing for a linear trend in the proportions — and is more powerful for it.
The scenario here: does the proportion of people with renal stones increase across age groups? This lesson runs it with rstatix on the renalstone data.
Cochran-Armitage hypotheses. H₀: there is no linear trend in the proportion across the ordered levels. Hₐ: the proportion changes monotonically (increases or decreases) with the ordered exposure.
We use the renalstone dataset from datarium and cross-tabulate stone status × age group (three ordered bands) with base R:
age
stone 30-39 40-49 50-59
yes 384 536 335
no 951 869 438
The proportion with a stone clearly rises across the age bands:
30-39 40-49 50-59
0.288 0.381 0.433
≈ 29% → 38% → 43% — a steady increase with age.
prop_trend_test() takes the 2 × k table and assigns scores (1, 2, 3, …) to the ordered columns by default:
# A tibble: 1 × 6
n statistic p p.signif df method
* <int> <dbl> <dbl> <chr> <dbl> <chr>
1 3513 49.7 1.78e-12 **** 1 Chi-square trend test
There is a significant increasing trend in the renal-stone proportion across age groups, χ²(1) = 49.7, p < 0.0001 — the risk rises with age. (Note 1 degree of freedom: the trend test uses the ordering to focus all its power on the linear component, unlike a plain chi-square which would have k − 1 df.)
Custom scores. By default the levels score 1, 2, 3, …. If the ordered variable has meaningful numeric values (e.g. doses 0, 10, 50 mg), pass them with score = c(0, 10, 50) so the trend reflects the real spacing.
library(rstatix)
library(ggpubr)
data("renalstone", package = "datarium")
xtab <- xtabs(~ stone + age, data = renalstone)
prop.df <- data.frame(
age = colnames(xtab),
prop = as.numeric(prop.table(xtab, margin = 2)["yes", ])
)
stat.test <- prop_trend_test(xtab)
ggbarplot(prop.df, x = "age", y = "prop", fill = "#3a86d4",
ylab = "Proportion with stone", xlab = "Age group") +
labs(subtitle = get_test_label(stat.test, detailed = TRUE))
A Cochran-Armitage test for trend showed that the proportion of individuals with renal stones increased significantly across the ordered age groups, χ²(1) = 49.7, p < 0.001 (29%, 38%, 43%).
The test assigns a score \(x_j\) to each ordered level \(j\) and tests whether the proportions \(p_j\) follow a line in those scores. The statistic is essentially a \(\chi^2\) on 1 degree of freedom based on the slope of proportion against score — equivalently \(z^2\) from a weighted linear regression of \(p_j\) on \(x_j\). Concentrating the test on the linear (trend) component is why it is more powerful than the general \((k-1)\)-df chi-square when a monotonic trend is the real alternative.
Test for a dose-response trend on your own ordered table. Edit the counts and re-run; the sandbox boots on first Run.
Ask Prova “I have a yes/no outcome across ordered dose levels — test whether the proportion shows a trend with the Cochran-Armitage test” — it answers with rstatix code you can run on your own table. The runtime is the judge. Ask Prova →
Your exposure isn’t ordered. The trend test only makes sense when the columns have a meaningful order (dose, age, stage). For unordered categories use a plain chi-square test.
You ignored the real spacing. Default scores are 1, 2, 3, … (equal spacing). If your levels are doses like 0, 10, 50, pass score = c(0, 10, 50) so the trend reflects the actual distances.
The proportions go up then down. The Cochran-Armitage test looks for a monotonic linear trend; a U-shaped pattern can give a non-significant result even though the groups clearly differ — inspect the plot, and consider a plain chi-square for any difference.
It tests whether a binomial (yes/no) proportion changes linearly across the ordered levels of an exposure — for example, whether a disease rate rises with dose or age. Also called the chi-square test for trend, it uses the ordering of the categories, making it more powerful than a plain chi-square for detecting a monotonic trend.
The plain chi-square test of independence tests whether the proportions differ at all (ignoring order), on k − 1 degrees of freedom. The Cochran-Armitage test uses the order of the columns to test specifically for a linear trend, on 1 degree of freedom — so it has more power when a trend is the real pattern.
prop_trend_test() scores the levels 1, 2, 3, … by default (equal spacing). If the ordered variable has real numeric values (e.g. doses), pass them via score = c(...) so the trend reflects the actual spacing between levels.
Fill the blank with prop_trend_test. For question 2, recall that the trend test focuses on a single direction (the linear component).
For question 2: the Cochran-Armitage test concentrates all its power on the linear trend — a single parameter (the slope of proportion against the ordered score) — so it uses 1 degree of freedom. A plain chi-square allows the proportions to differ in any pattern, costing k − 1 degrees of freedom and diluting its power against a monotonic alternative.
You can now run the Cochran-Armitage trend test in R: cross-tabulate the 2 × k table and run prop_trend_test() to test for a linear trend in a proportion across ordered categories — more powerful than a plain chi-square because it uses the ordering. Set custom scores when the levels have meaningful spacing, and reach for it whenever you expect a dose-, age- or severity-response.
Prove you can do it. Master the whole Categorical Analysis in R series — track your path, build projects, and earn a certificate.
Go Pro — unlimited Prova on your own data and a verifiable certificate that proves the skill.
from $15/mo billed yearly
✓ You're Pro — keep going. The runtime is the judge.
Get new R & Python lessons by email
Practical, reproducible, no spam. Unsubscribe anytime.
Double opt-in. We never share your email.
Every result on this page was produced by the code shown, run at build time against a pinned R environment — edit any block and Run to reproduce it yourself.
@online{2026,
author = {},
title = {Cochran-Armitage {Trend} {Test} in {R:} {Test} a {Trend} in
{Proportions}},
date = {2026-06-23},
url = {https://www.datanovia.com/learn/biostatistics/categorical/cochran-armitage-trend-test-in-r},
langid = {en}
}