AdvancedReporting guideline: CONSORT 2025Independently reviewed, not yet spot-checked by a human

Randomised controlled trial

What the statistics section of an RCT is doing, how to read one in order, and the parts textbooks rarely cover but real trials always have — interim analyses, early stopping, and the patient who was counted anyway.

What this chapter answers

You open a randomised controlled trial (RCT). There is a CONSORT flow diagram, a Table 1, a p-value attached to the primary outcome, and a row of subgroup estimates in a forest plot. This chapter is about what each of those is defending against, and which cell should make you stop reading and look harder.

One real trial runs through the whole chapter: Elmunzer and colleagues, NEJM 2012, testing whether a rectal indomethacin suppository given right after ERCP prevents pancreatitis. It was chosen for three reasons — its participant-level data are public (one line from the medicaldata package), its design includes an interim analysis and an early stop that textbooks rarely demonstrate, and it happens to contain an unusually clean illustration of intention-to-treat.

What randomisation actually buys

The hardest problem in observational research is that people who receive a treatment differ from people who do not, before any treatment is given. Clinicians prescribe to patients who appear to need it, so “received the drug” carries information about “was sicker” and the two cannot be separated afterwards. This is confounding by indication.

Randomisation solves it crudely but completely: assignment is decided by a random number and by nothing about the patient. In expectation the arms then match on every characteristic — the ones you thought of, the ones you did not, and the ones nobody can measure. That last category is the real prize. Statistical adjustment can only handle confounders you measured; randomisation handles the ones you never knew existed.

In this trial, randomisation happened after the ERCP was finished. That looks odd until you see the eligibility criteria: half of them are procedural facts nobody knows in advance — more than eight cannulation attempts, a precut sphincterotomy — so a patient’s eligibility is not determined until the procedure is over.

Concealment and blinding are two different defences

Three separate things hide inside the word “randomised”, and they fail in different ways. Randomisation decides who goes into which arm by chance. Allocation concealment keeps the upcoming assignment unknowable to whoever is entering patients, right up to the moment a patient is entered. Blinding keeps the assignment unknown to people after it has been made. A trial can do the first and skip the other two, and its abstract will still say “randomised”.

Allocation concealment protects against selection bias. If the person recruiting can foresee what the next assignment will be, they can act on it — wait for a healthier patient before entering the next one, discover that this one is not eligible after all, or reorder the queue. None of that requires bad faith; a clinician who believes the drug works will find it hard not to steer the sicker patient towards it. And the damage is done at the moment of allocation: the arms stop being comparable, which is exactly the confounding by indication that the section above said randomisation had solved. In this trial the randomisation schedule was generated centrally at the coordinating centre and stratified by site. The paper does not describe how each assignment reached the procedure room, so how tightly it was concealed is not something this page can assert; what it does say is that randomisation happened only after the ERCP was complete and eligibility settled, which removes the recruiter’s opportunity to act on a foreseen assignment in the first place. Central randomisation, pharmacy-controlled allocation, and sequentially numbered opaque sealed envelopes are the usual mechanisms; “sealed envelopes” without the numbering and the opacity is not one of them.

Blinding protects against something else — what happens after the assignment. Ask who was kept unaware, one group at a time: the patients, the clinicians treating them, whoever ascertains and adjudicates the outcome, and the analysts. Patients who know their arm report symptoms differently; clinicians who know it hand out co-interventions differently (performance bias); outcome assessors who know it classify borderline cases differently (detection bias). This trial used identical-appearing placebo suppositories, and the staff who cared for patients after the procedure and recorded the follow-up data were unaware of the assignment. That matters here because the primary outcome is a composite of new upper abdominal pain, an enzyme threshold, and a decision to keep the patient in hospital — and two of those three run through clinical judgement.

Step one: the CONSORT flow diagram

The flow diagram answers one question: between “somebody was looked at” and “somebody was counted in the analysis”, how many people were lost, and why.

Start with what a standard one looks like. The diagram below follows the CONSORT boxes, but every count in it was invented to show the structure — none of it is this trial’s, or any published trial’s:

A CONSORT flow diagram in four stages, top to bottom, each on a pale band with its stage name set vertically down the left edge. Enrolment: a box at the top reads assessed for eligibility, 1240 people; on the way down, a branch to the right leads to an excluded box of 690 with three reasons and counts beneath it (Did not meet inclusion criteria, 470; Declined to participate, 145; Other reasons, 75); the trunk continues down into randomised, 550. Allocation: the randomised box splits into two arms, 275 on the left and 275 on the right, each listing how many received the allocated treatment, how many did not, and the two reasons why. Follow-Up: one box per arm giving those lost to follow-up (9 on the left, 7 on the right) and those who discontinued, with a line noting that patients who discontinued are still analysed as allocated. Analysis: one box per arm giving the number analysed (266 and 268) and the number excluded from analysis with the reason. A line of red text at the foot of the diagram states that these counts are hypothetical and come from no published trial.
What a standard CONSORT diagram looks like. The counts inside it are hypothetical, invented to show the structure; they are neither this chapter's trial nor any published trial. The two boxes to look at are the top pair, assessed for eligibility and excluded with its reasons, because those are exactly the two this page cannot fill in.Plotting script figures/scripts/D3-consort-subgroup.R

Four stages, top to bottom: Enrolment (assessed, excluded with reasons, then randomised), Allocation (how many went to each arm, and how many in each arm did and did not receive what they were allocated), Follow-Up (lost to follow-up and discontinued, per arm), and Analysis (analysed and excluded from analysis, with reasons, per arm).

The relationship between the last two stages is worth noting now. In the illustration, 5 patients in the intervention arm discontinued the allocated treatment and were still counted in the analysis; the ones who actually left the denominator are the 9 with no primary outcome data. That is intention to treat drawn as boxes, and step four below says it in words.

It has two halves. The lower half — everything from Allocation down — can be rebuilt from participant-level data:

library(medicaldata)
data(indo_rct, package = "medicaldata")

# Arms after randomisation
table(indo_rct$rx)

# Primary outcome (post-ERCP pancreatitis) by arm
table(indo_rct$rx, indo_rct$outcome)

Verified with R 4.6.0 and medicaldata 0.2.0

That gives 602 patients randomised — 295 to indomethacin and 307 to placebo — with follow-up complete in both arms.

The upper half is not obtainable. Those are the top two boxes of the diagram above: assessed for eligibility, and excluded with its list of reasons. The illustration puts 1,240 and 690 in them; for the real trial in this chapter, this page cannot fill them in. How many were screened, how many excluded, and for what reasons, are not in this file, because a participant-level dataset contains only those who were randomised; everyone screened out was never a row. We also read the published Methods and Results in full: those counts appear in no sentence anywhere. They exist only inside the Figure 1 image.

The only way through is to open the figure and read the counts off it. How to read a clinical research paper does exactly that, and redraws the counts as a flow diagram. Doing so surfaces something worse: even the published Figure 1 does not start at assessed for eligibility. Its top box is the 799 patients who gave consent, and the number of people who were looked at is recorded nowhere in the paper at all.

Step two: Table 1, and the p-value that should not be there

Table 1 lists baseline characteristics by arm. The question you are asking is: do these arms look similar enough? But the way to ask it is not to look for p-values.

Significance testing across arms in an RCT is common and wrong, for a simple reason: the null hypothesis — that the arms were drawn from the same population — is true by construction under randomisation. Testing something you already know to be true yields no information, and any significant result is a type I error by definition.

What to look at instead is the standardised mean difference (SMD). It does not inflate with sample size, and the convention is that |SMD| < 0.1 counts as balanced. The same logic reappears in propensity score matching; the method page covers it.

Step three: the primary outcome and effect measures

n_indo <- sum(indo_rct$rx == "1_indomethacin")
n_plac <- sum(indo_rct$rx == "0_placebo")
e_indo <- sum(indo_rct$rx == "1_indomethacin" & indo_rct$outcome == "1_yes")
e_plac <- sum(indo_rct$rx == "0_placebo"      & indo_rct$outcome == "1_yes")

p_indo <- e_indo / n_indo          # risk on treatment
p_plac <- e_plac / n_plac          # baseline risk

arr <- p_plac - p_indo             # absolute risk reduction
nnt <- 1 / arr                     # number needed to treat
rr  <- p_indo / p_plac             # risk ratio
rrr <- 1 - rr                      # relative risk reduction

fisher.test(matrix(c(e_indo, n_indo - e_indo,
                     e_plac, n_plac - e_plac), nrow = 2))

Fisher's exact test was pre-specified in the protocol — it was not chosen after seeing the data.

MeasureValueHow to read it
Risk on treatment27/295 = 9.2%Pancreatitis despite the drug
Risk on placebo52/307 = 16.9%The baseline risk
Risk ratio (RR)0.54 (95% CI 0.35–0.84)Risk becomes 0.54× what it was
Relative risk reduction46%The number that reads best in a headline
Absolute risk reduction7.8 percentage pointsThe risk actually removed
Number needed to treat13Treat 13 to prevent one case
Fisher’s exact p0.0053See the next section — the threshold is not 0.05

The gap between RRR and ARR is the row to stop on. The same data described as “a 46% reduction” and as “a 7.8 percentage point reduction” leave completely different impressions. Relative measures are untethered from baseline risk, so they always look larger; how much a patient actually gains depends on how much risk they had to begin with. In a low-risk population the same RRR converts into an ARR small enough to be clinically irrelevant.

A paper or a slide that reports RRR without ARR or NNT is a warning sign in itself.

Step four: intention to treat

The rule of intention-to-treat (ITT) analysis is: analyse every patient in the arm they were randomised to, regardless of what they actually received.

This is counterintuitive — why count someone in the drug arm when they never got the drug? Because the moment you start removing people, you have to use information that only exists after randomisation to decide whom to remove. And whether a patient took the treatment is itself usually related to prognosis: sicker patients are likelier to vomit, to withdraw, to be too unwell to continue. Removing them hands back the comparability randomisation just paid for.

This trial contains a clean instance. The paper states it plainly: one patient assigned to indomethacin could not retain the suppositories, and was analysed in the indomethacin arm regardless. That is ITT executed literally.

Per-protocol (PP) analysis, by contrast, counts only those who complied. It answers a different question — what happens under full adherence — at the cost of the protection randomisation provided. The usual relationship is:

  • Superiority trials: ITT is conservative. Non-adherence pulls the arms toward each other, so the effect is understated. ITT is therefore the primary analysis.
  • Non-inferiority trials: the direction reverses. The same dilution makes the arms look more alike, which makes it easier to conclude non-inferiority. Non-inferiority trials must therefore report both ITT and PP, and the conclusion only holds if they agree.

Step five: sample size, interim analyses and early stopping

This is the section textbooks skip and real trials cannot.

The protocol planned to enrol 948 patients (474 per arm), on the assumption that placebo risk was 10% and treatment would halve it to 5%, giving at least 80% power at a two-sided α of 0.05 (using Fisher's exact).

Enrolment actually stopped at 602. The data and safety monitoring board (DSMB) saw a clear advantage at an interim analysis and recommended stopping under the pre-specified rule.

One detail matters more than it looks: because 2 interim analyses were performed, the threshold for declaring significance at the end was not 0.05 but 0.041.

Why? Every additional look at accumulating data is another opportunity to make a type I error. Testing at 0.05 each time pushes the overall error rate well above 0.05. An O'Brien-Fleming boundary with a Lan-DeMets alpha spending function allocates a total budget of 0.05 across the looks — the interim analyses spend a little (their thresholds are severe, so stopping early is hard), and what remains funds the final analysis, which is why the final threshold sits just under 0.05.

Step six: subgroup analyses

The subgroup forest plot usually sits near the end. Three things to hold onto while reading it:

  1. Subgroup analyses are always underpowered. The sample size was chosen for the primary outcome; cut it into subgroups and every cell is far smaller. Failing to detect a difference is the expected outcome, not evidence of no effect.
  2. Read the test for interaction, not each subgroup’s own p-value. “Significant in A, not in B” is entirely compatible with identical effects in both, if A simply has more patients. Whether the effects genuinely differ is a different question, and only an interaction test answers it.
  3. Pre-specified and post hoc are not the same evidence. Post hoc subgroup findings are hypothesis-generating and nothing more.

That point applies to this trial too. Its exploratory subgroup analyses mix pre-specified subgroups with ones added post hoc, and the paper does not separate the two. So the sentence below — that the direction of benefit was consistent across subgroups — is supportive observation compatible with the primary result, not confirmatory evidence; the post hoc cells have no prior statistical plan protecting them, so their type I error rate is uncontrolled.

This trial’s subgroup analyses detected no interaction between subgroups — the direction of benefit was the same whether or not a pancreatic stent was placed, and across the sphincter of Oddi dysfunction categories. That is far more credible than a striking finding confined to one subgroup, but hold on to point 1 above: subgroups are underpowered by design, so failing to detect an interaction is not evidence that the effect is identical in every subgroup.

The paper’s own forest plot cannot be reproduced here, but the same public data can be recomputed into one. Below is that recomputation, over 6 subgroup variables that the indo_rct file already carries:

A subgroup forest plot in three column blocks. The left block holds the subgroup names and, in two columns, the events over patients in the indomethacin and placebo arms for each stratum. The middle block plots each stratum's risk ratio and 95% confidence interval on a logarithmic scale ticked at 0.1, 0.25, 0.5, 1, 2, with a vertical dashed line at a risk ratio of 1 labelled favours indomethacin on its left and favours placebo on its right. The right block gives the risk ratio and interval as text, and then, in the final column, the p-value for interaction — one value per subgroup variable, printed on that variable's heading row, not one per stratum. The top row is the whole trial, 27 of 295 against 52 of 307, drawn as a diamond. Below it, in order, are Suspected sphincter of Oddi dysfunction, Pancreatic duct stent placed, Previous post-ERCP pancreatitis, Pancreatic sphincterotomy, Sex, Trainee involved in the procedure -- 6 variables of two strata each, 12 rows in all. All 12 point estimates fall to the left of the null line, between 0.30 and 0.71, and 6 of the intervals cross it; no interaction p-value is small, the smallest being 0.23. A line of red text at the foot states that these estimates were recomputed from medicaldata::indo_rct and are not a copy of the published subgroup table.
A subgroup forest plot recomputed from indo_rct. The final column is the p-value for interaction, one per subgroup variable rather than one per stratum, and that column is what a subgroup analysis is read from. Both the layout and the reading differ from the meta-analysis forest plot on method page B7-04: there a row is a study, the diamond is a pooled estimate across studies, and the thing to look at is heterogeneity and study weights; here a row is a stratum inside one trial, the diamond is the whole trial, and the thing to look at is the last column.Plotting script figures/scripts/D3-consort-subgroup.R

Recomputing is not the same as copying the published table. The paper mixes pre-specified with post hoc subgroups and never says which model produced which row, so all this figure can offer is what one clearly specified model makes of one public dataset: Katz intervals for the stratum-specific risk ratios, and a Wald test on the product term of a log-link Poisson model with a robust variance for the interaction.

Read it against the three rules above. Whether a pancreatic duct stent was placed makes point 2 best: the estimate is 0.30 without a stent and 0.60 with one, roughly a twofold gap — and yet the stratum with the larger apparent effect is the one whose interval crosses the null line (it holds only 106 patients), while the other stratum’s does not. Read off the per-stratum p-values alone, that becomes “it only works in patients who got a stent”; the p-value for interaction is 0.29, and these data did not detect a difference between the two strata. Across all six variables the smallest interaction p-value is 0.23, still nowhere near small enough to carve up the population on.

All 12 point estimates sit left of the null line, which is compatible with the primary result; but every stratum’s interval is wider than the one on the overall row, and 6 of them cross the null line. That is point 1 — underpowered by design, not evidence that the subgroup fails to benefit.

This and the meta-analysis forest plot on B7-04 are two different figures that happen to look alike. There, a row is a study and the diamond pools across studies, so heterogeneity is the question. Here, a row is a stratum within one trial and the diamond is the trial itself, so the last column is the question. Reading trial reports, it is this one you meet.

Common misuses

MisuseWhy it is wrong
Testing Table 1 for between-arm differencesThe null is true by construction under randomisation; the test carries no information
Reporting RRR without ARR or NNTRelative measures are untethered from baseline risk and overstate the benefit
Excluding non-adherent patients from the primary analysisDestroys the comparability randomisation bought, and exclusion correlates with prognosis
Reporting only ITT in a non-inferiority trialThe dilution effect biases towards concluding non-inferiority
Treating an early-stopped trial’s effect size as the best estimateEarly stopping systematically overestimates
Claiming an effect “only in subgroup X” from that subgroup’s p-valueUse the interaction test; subgroups are underpowered by design
Reading a non-significant result as “no difference”It means this trial did not detect one; equivalence needs a non-inferiority design with a pre-specified margin

Reproducing every number on this page

/opt/homebrew/bin/Rscript figures/scripts/D3-rct-indo.R
/opt/homebrew/bin/Rscript figures/scripts/D3-consort-subgroup.R

The scripts write figures/out/D3-rct-indo.stats.json and figures/out/D3-consort-subgroup.stats.json, and every figure quoted above is read from one of them. None is typed by hand. In the second file the CONSORT block is marked hypothetical: true — those counts are invented for the illustration — while the subgroup block is computed from the public data.

Read the figure

The answer comes from the same statistical output that produced this page's figures, not from a number typed in beside them.

The same event counts can be written as a relative risk reduction or as an absolute one. The abstract reports only the first. What does that do to the reader?

Show the answer and why

Correct answer: It matters. The absolute reduction is only 0.078, fewer than eight events per hundred treated, while a relative measure is detached from baseline risk

0.460 and 0.078 are two ways of writing the same event counts, and they leave very different impressions. A relative measure is unaffected by baseline risk, so it looks the same size whatever the baseline is, while what a patient actually gains depends on how high their risk was to start with. In a low-risk population the same relative reduction converts into an absolute reduction too small to matter clinically. The risk ratio of 0.540 is a relative measure too, so it cannot answer how much risk a given patient avoids either. Reporting the relative reduction without the absolute reduction or the number needed to treat is the standard way of overstating a benefit.

This trial ran two interim analyses, and the threshold for declaring significance at the end is not the two-sided 0.05. Which statement is right?

Show the answer and why

Correct answer: The final threshold is 0.041, because every extra look at the data is another chance of a type I error and the interim looks spend part of the budget

An alpha spending function divides a total type I error budget of 0.050 across the looks. The interim looks spend a little of it under a boundary strict enough that stopping early is hard, and what is left goes to the final analysis, which is why the final threshold comes out slightly below 0.050, here 0.041. Using 0.050 at every look would push the overall error rate far above 0.050. The 0.005 is the p value this trial actually produced; it is the number compared against the threshold, not the threshold itself, and treating an observed result as the threshold would make every trial significant by construction.

On the subgroup forest plot, the stratum without a pancreatic duct stent has a risk ratio further from the null than the stratum with one, yet only the former has an interval crossing the null. How should that be read?

Show the answer and why

Correct answer: The interaction p value for this variable is 0.29, so these data detected no difference between the strata

Whether two strata differ is answered by the interaction test, not by each stratum's own interval, and 0.29 is nowhere near small enough to split a population on. As for why the stratum with the apparently larger effect is the one crossing the null: it holds only a hundred or so people, so its interval is wider. 0.30 and 0.60 differ by roughly a factor of two, but both estimates are very imprecise, and a gap of that size is ordinary in subgroup analysis. None of the six variables has a small interaction p value, and all twelve stratum estimates fall on the same side of the null, which is consistent with the main result rather than evidence that one group alone benefits.

The demonstration CONSORT diagram fills in the counts assessed for eligibility and excluded at the top. This page cannot fill in the same two boxes for the real trial it uses. Why not?

Show the answer and why

Correct answer: Because a screened-out person was never a row in a participant-level file; the demonstration figure can print 690 only because it is constructed

A participant-level file contains, by definition, only those who were randomised, so the lower half of the diagram can be rebuilt and the upper half cannot. The demonstration figure can print 1240 and 690 because both were constructed to show the structure. The real trial's screening and exclusion counts appear nowhere in the prose of its Methods or Results and live only inside Figure 1, which means full-text search, grep and a language model reading the abstract all miss them. As for 266, that is the number analysed in the demonstration figure; it belongs to the lower half and was always reconstructible, and note that people who discontinued treatment are still counted in the analysis, while what actually leaves the denominator is the handful with no primary outcome data.

One patient assigned to indomethacin could not retain the suppositories, and the paper still analysed him in the indomethacin arm. What is the reason?

Show the answer and why

Correct answer: Because deciding who to remove uses information that exists only after randomisation and is tied to prognosis, so the arm's 27 events count by assignment

Intention to treat analyses everyone by the arm they were assigned to. That is not formalism: whether a patient can retain a drug is itself related to prognosis, since sicker patients are likelier to vomit it back or to withdraw, so any move based on what someone actually received regroups people using information that appeared after randomisation and gives back the comparability randomisation bought. Folding this patient into the placebo arm's 52 events breaks the same rule and in a worse direction, because it books a failure caused by being unwell to the control group. The treatment arm's 27 events are counted by assignment. The first answer reads intention to treat as sample-size management. It is not there to keep the count up: dropping this patient altogether would cost so little power that the conclusion would not change. What it protects is comparability, because once people may be moved according to what they actually received, the ones moved out are systematically those with the worse prognosis, and the size of that bias does not depend on the sample size, so enrolling more people afterwards does not undo it. A per-protocol analysis answers a different question, and in a superiority trial it is not the primary one.

This is a four-centre trial and the abstract says multicentre. Can a reader infer better generalisability from that?

Show the answer and why

Correct answer: No. Of the 602 participants, 413 came from a single site, so enrolment was never spread evenly

Of the four centres, Indiana University alone enrolled 413 participants, the remaining three together enrolled less than half the total, and the smallest contributed a single-digit number. The multicentre label tells you how many sites are named, not how enrolment was distributed among them. A reader judging generalisability should ask whether the eligibility criteria, the care pathway and the patients at the dominant site resemble the population they have in mind. A second inference also fails: with so few patients at the smallest sites, any site-specific estimate would be hopelessly imprecise, so these data do not support a post hoc subgroup analysis by centre.

Watch next

Randomized control trial (RCT) explained
ENHenrik's Lab· 3 minThree and a half minutes on what randomisation is actually solving. Worth watching before this chapter.
Intention-to-treat analysis: What is it and why is it important?
ENTerry Shaneyfelt· 5 minSpecifically on why you cannot drop a patient who did not take the drug. Pairs with step four.
Intention-to-treat (ITT) and other forms of data analysis
ENCochrane Austria· 7 minGoes further than the previous one — ITT against per-protocol and as-treated, with worked cases.

Sources and licences

Report a content problem

The statistics on this site are written by AI and reviewed by AI; a human only spot-checks. What you can see may be what we cannot.

The more specific, the more fixable — e.g. which sentence disagrees with which textbook or paper.

Needed only if you want a reply; reports without it are still read.

Sent along with your report

These are attached automatically. You can drop any of them.