AdvancedIndependently reviewed, not yet spot-checked by a human

Table 1 and standardised mean differences

Why Table 1 asks a different question in a trial than in an observational study, why the standardised mean difference does not inflate with sample size, where the |SMD| < 0.1 convention came from, and how to decide between mean and median and where to put missing values.

What this table is answering

The first table in a paper is almost always a table of baseline characteristics, but it is not answering the same question in every design — this is the single most important thing on this page, and every other detail follows from it.

DesignWhat Table 1 answersWhat the reader decides from it
RCT“Did this particular random allocation happen to produce two similar groups?”Whether a chance imbalance is large enough to be worth adjusting for
Cohort / case-control / real-world data“How different were these two groups to begin with?”How severe the confounding is, and whether adjustment could plausibly cope
After propensity score matching or weighting“Did matching or weighting actually remove the difference?”Whether the balancing procedure succeeded — this is its acceptance test
Any study“Who are these people? Do my patients resemble them?”External validity, the most underrated use of Table 1

The difference is very practical. In an RCT, any difference between the arms can only come from luck, because allocation had nothing to do with patient characteristics; you already know the answer to “is there a difference”, and Table 1 only shows you how big it is. In an observational study the arms differ because they really are different — clinicians prescribe one drug to one kind of patient — so Table 1 is telling you the size of the confounding problem.

The example used here

survival::pbc is the Mayo Clinic trial in primary biliary cholangitis (PBC), 418 patients in total. It happens to contain the first two rows of the table above inside one file:

  • 312 patients were randomised to D-penicillamine or placebo → that is the Table 1 of an RCT
  • 106 patients declined randomisation but agreed to be followed in a registry → “randomised vs registry” is a genuine observational comparison

Same data, same seven or eight variables. Change how you split the rows and the meaning of the whole table changes with it.

How the standardised mean difference is computed

The standardised mean difference (SMD) converts “how far apart are these groups” into “how many standard deviations apart are they”. For a continuous variable:

d=xˉ1xˉ2(s12+s22)/2d = \frac{\bar{x}_1 - \bar{x}_2}{\sqrt{(s_1^2 + s_2^2)/2}}

The denominator is the root mean square of the two standard deviations, not the pooled SD. The two differ slightly when the groups are of unequal size, and Table 1 conventionally uses the former.

For a binary variable, treat the proportion as the mean of a Bernoulli variable, whose variance is fixed by the proportion itself:

d=p1p2[p1(1p1)+p2(1p2)]/2d = \frac{p_1 - p_2}{\sqrt{[p_1(1-p_1) + p_2(1-p_2)]/2}}

A variable with three or more categories needs Austin’s multinomial extension: write the proportions of the kk categories as a (k1)(k-1)-dimensional vector TT, and take the Mahalanobis distance using the average covariance matrix SS of the two groups:

d=(T1T2)S1(T1T2)d = \sqrt{(T_1 - T_2)^{\top} S^{-1} (T_1 - T_2)}

What all three formulas share is that the denominator depends only on spread, never on sample size. That is exactly why the SMD replaces the p-value here, and the next section demonstrates it with an experiment.

Running it yourself

library(survival)
data(pbc, package = "survival")

pbc$arm <- factor(pbc$trt, levels = c(1, 2),
                  labels = c("D-penicillamine", "Placebo"))

# ── SMD by hand: continuous variable ────────────────────
smd_cont <- function(x, g) {
  ok <- !is.na(x) & !is.na(g); x <- x[ok]; g <- droplevels(factor(g[ok]))
  m <- tapply(x, g, mean); s <- tapply(x, g, sd)
  unname((m[1] - m[2]) / sqrt((s[1]^2 + s[2]^2) / 2))
}

# ── SMD by hand: binary variable ────────────────────────
smd_bin <- function(x, g) {           # x is coded 0/1
  ok <- !is.na(x) & !is.na(g); x <- as.numeric(x[ok]); g <- droplevels(factor(g[ok]))
  p <- tapply(x, g, mean)
  unname((p[1] - p[2]) / sqrt((p[1] * (1 - p[1]) + p[2] * (1 - p[2])) / 2))
}

smd_cont(pbc$age, pbc$arm)      # age
smd_bin(pbc$sex == "m", pbc$arm)  # sex

# ── The one-line version you would really use (tableone would not ──
# ── install on this machine, hence the manual computation above) ──
# library(tableone)
# CreateTableOne(vars = c("age", "sex", "bili", "albumin", "stage"),
#                strata = "arm", data = pbc) |> print(smd = TRUE, nonnormal = "bili")

Verified with R 4.6.0 and survival 3.8.6. In practice tableone::CreateTableOne() gives you all of this in one line; it is done by hand here so you can see the formula.

Two Table 1s from the same data

1. The RCT Table 1: D-penicillamine vs placebo

VariableD-penicillamine (n = 158)Placebo (n = 154)Missing (drug / placebo)|SMD|p (shown to make a point; it does not belong in a paper)
Age (years)
mean ± SD / median (IQR)
51.4 ± 11.0
51.9 (43.0–58.9)
48.6 ± 10.0
48.1 (41.4–55.8)
0 / 00.2700.018
SexFemale 137 (86.7%); Male 21 (13.3%)Female 139 (90.3%); Male 15 (9.7%)0 / 00.1110.421
Serum bilirubin (mg/dL)
mean ± SD / median (IQR)
2.87 ± 3.63
1.40 (0.80–3.20)
3.65 ± 5.28
1.30 (0.72–3.60)
0 / 00.1710.133
Serum albumin (g/dL)
mean ± SD / median (IQR)
3.52 ± 0.44
3.56 (3.21–3.83)
3.52 ± 0.40
3.54 (3.34–3.78)
0 / 00.0180.874
Serum cholesterol (mg/dL)
mean ± SD / median (IQR)
365 ± 210
316 (248–417)
374 ± 252
304 (254–377)
18 / 100.0380.747
Platelet count (x10^9/L)
mean ± SD / median (IQR)
259 ± 100
255 (190–322)
265 ± 91
260 (207–322)
2 / 20.0670.554
OedemaNone 132 (83.5%); Untreated/resolved 16 (10.1%); Despite diuretics 10 (6.3%)None 131 (85.1%); Untreated/resolved 13 (8.4%); Despite diuretics 10 (6.5%)0 / 00.0580.877
Histologic stageStage 1 12 (7.6%); Stage 2 35 (22.2%); Stage 3 56 (35.4%); Stage 4 55 (34.8%)Stage 1 4 (2.6%); Stage 2 32 (20.8%); Stage 3 64 (41.6%); Stage 4 54 (35.1%)0 / 00.2460.201

2. The observational Table 1: accepted randomisation vs declined it

VariableRandomised (n = 312)Registry (n = 106)Missing (randomised / registry)|SMD|
Age (years)50.0 ± 10.6
49.8 (42.2–56.7)
52.9 ± 9.8
53.0 (46.0–61.0)
0 / 00.280
SexFemale 276 (88.5%); Male 36 (11.5%)Female 98 (92.5%); Male 8 (7.5%)0 / 00.136
Serum bilirubin (mg/dL)3.26 ± 4.53
1.35 (0.80–3.42)
3.12 ± 4.04
1.40 (0.72–3.08)
0 / 00.032
Serum albumin (g/dL)3.52 ± 0.42
3.55 (3.31–3.80)
3.43 ± 0.43
3.47 (3.12–3.72)
0 / 00.208
Serum cholesterol (mg/dL)370 ± 232
310 (250–400)
Not measured
Not measured
28 / All
Platelet count (x10^9/L)262 ± 96
257 (200–322)
242 ± 105
226 (166–286)
4 / 70.201
OedemaNone 263 (84.3%); Untreated/resolved 29 (9.3%); Despite diuretics 20 (6.4%)None 91 (85.8%); Untreated/resolved 15 (14.2%); Despite diuretics 0 (0%)0 / 00.393
Histologic stageStage 1 16 (5.1%); Stage 2 67 (21.5%); Stage 3 120 (38.5%); Stage 4 109 (34.9%)Stage 1 5 (5%); Stage 2 25 (25%); Stage 3 35 (35%); Stage 4 35 (35%)0 / 60.093

Stacking the two sets of |SMD| values on one axis is the clearest way to see it. That plot is called a Love plot, and it is standard equipment in propensity score work:

Love plot of the absolute standardised mean difference for seven baseline variables. Circles compare the two randomised arms, triangles compare the randomised group with the registry group, and a dashed line marks 0.1. Most circles sit near the line while several triangles lie well to the right of it.
The same pbc data split two ways. Circles are the two randomised treatment arms; triangles are patients who accepted randomisation versus those who declined it. The dashed line is the conventional 0.1.Plotting script figures/scripts/B1-01-table1.R

The row worth stopping on: even the two randomised arms have 4 variables with |SMD| above 0.1, age being 0.270. This is not a failure of randomisation. It is what one draw of n = 312 routinely produces. On the other line, 5 variables exceed 0.1, and oedema reaches 0.393 — that is what “these two groups were never alike” looks like.

Why the SMD rather than a p-value

Here is an experiment using the data on this page. Take the 312 randomised patients and duplicate the whole file ten times, giving 3120 rows. Every group mean, every standard deviation and every distributional shape is unchanged; only the sample size is ten times larger.

Original (n = 312)Ten copies (n = 3120)
Age |SMD|0.2700.271
Age t-test p0.018< 0.001

The SMD barely moves — the 0.001 of drift comes only from the n1n-1 denominator inside the standard deviation — while the p-value drops by 11.6 orders of magnitude. A p-value encodes “how large is the difference” and “how many people are there” at the same time, and Table 1 only wants to ask the first. This is why a claims database study with tens of thousands of patients, such as one built on Taiwan’s National Health Insurance data, routinely reports p < 0.001 down the entire column, and why that column carries no information at all.

An RCT has a second and more fundamental reason. The null hypothesis — that both arms were drawn from the same population — is true by construction under randomisation. You are testing a hypothesis whose answer you already know, so any significant result is by definition a type I error. The RCT table on this page tested 8 variables; the smallest p-value is 0.018, with 1 below 0.05 — entirely as expected. If those tests were independent of one another, the probability of at least one “significant” result across 8 variables would be about 33.7%, and about 64.2% across the 20 variables a paper commonly reports. Baseline variables are usually correlated with one another — age with stage, bilirubin with albumin — so treat both figures as an order-of-magnitude guide rather than the exact probability for this table. The direction is unaffected: the more variables you test, the less a stray “significant” result deserves attention.

Where the |SMD| < 0.1 line came from

The threshold is quoted as if it were law, but its provenance is looser than that. It comes out of the propensity score literature — the usage in Normand and colleagues in 2001, generalised through Austin’s series of methodological papers — and the argument is that simulations show residual |SMD| below 0.1 usually leaves bias small enough to ignore after matching.

Three things to remember:

  • It is a convention, not a test. There is no significant side and non-significant side of 0.1. There is no material difference between 0.09 and 0.11.
  • For an important confounder even 0.05 may be too loose. Whether to tighten the threshold depends on how strongly that variable acts on the outcome, not on which row it happens to be.
  • For an unimportant variable, exceeding 0.1 usually needs no action. An imbalance in a variable unrelated to the outcome cannot create confounding.

A looser threshold of 0.25 also circulates, from the earlier propensity score literature, so do not be surprised to see something other than 0.1 — but a paper must state which line it used.

Mean or median: look at the distribution, not at habit

The two tables above deliberately print mean ± SD and median (IQR) side by side, so you can see where the two part company. Serum bilirubin is the classic case:

Histogram of serum bilirubin for all pbc patients. The distribution is strongly right-skewed with a long tail, the mean line sits far to the right of the median line, and the mean minus one standard deviation falls below zero.
The distribution of serum bilirubin. The solid line is the mean, the dashed line the median. Skewness is 2.7, and the mean minus one standard deviation is -1.19 — already negative.Plotting script figures/scripts/B1-01-table1.R

The mean is 3.22 with an SD of 4.41, while the median is only 1.4 (IQR 0.8–3.4). The damning part is that mean − SD = -1.19, a negative number, when the smallest value actually observed is 0.3. Write it as 3.22 ± 4.41 and the symmetric interval that appears in the reader’s head simply does not exist in this dataset.

The rule is straightforward:

  • Roughly symmetric → mean ± SD. It carries more information, and it is the quantity a t-test or a linear model will use later.
  • Clearly skewed, outlier-prone, or bounded by nature (length of stay, hospital costs, bilirubin, CRP, follow-up time) → median (IQR).
  • Reporting both in Table 1 is entirely acceptable. One extra column costs far less than misleading the reader.

Missing values: they deserve their own row, and they should get one

They do — and honesty is not the only reason. Look at the cholesterol row of the second table: every one of the 106 registry patients is missing that value, because the 106 patients who declined randomisation never had the trial’s blood panel drawn (chol, copper, alk.phos, ast, trig, ascites, hepato, spiders are all in the same position). This is not scattered missingness; it is an entire group never measured. There is no SMD to compute, so the cell can only be left blank and annotated.

If Table 1 prints percentages without missingness counts, this disappears from the page entirely and the reader assumes both groups were measured. A denominator shrinking quietly is the commonest source of misreading in a baseline table.

Three practical points:

  • Print the count of missing values and the denominator. “n = 106, cholesterol missing in 106” reads very differently from “n = 106”.
  • State which denominator the percentages use. Complete cases and the full group size give different numbers; both are in use, and either is fine as long as it is stated.
  • Missingness can itself be the finding. In the example above, “not measured” and “declined randomisation” are two faces of the same fact. Treating missingness as a category of its own often exposes the selection mechanism.

How to read someone else’s Table 1

Four moves, from the top down:

  1. Read the two column ns first, then the missingness in each row. Whether the denominator shrinks on the way down decides what every percentage below it means.
  2. Check whether there is an SMD column. If there is not, estimate one in your head for the two or three variables you care about: the difference divided by roughly the standard deviation is a serviceable approximation.
  3. Check which summary each continuous variable uses, and whether that summary fits the distribution. A mean ± SD on length of stay is a warning sign.
  4. Look at who these people are. Median age, sex ratio, disease stage — do your patients fall inside this distribution? This step has nothing to do with balance, but it decides whether the paper is any use to you.

Common misuses

MisuseWhy it is wrong
Printing between-arm p-values in an RCT Table 1The null is true by construction, so a significant result can only be a type I error; CONSORT advises against it explicitly
Judging balance by p-value in a large database studyThe p-value inflates with n; at tens of thousands of patients the whole column reads p < 0.001 and says nothing
Selecting model covariates from Table 1 p-valuesAdjustment is decided by causal structure (the DAG), not by which variable happened to be imbalanced
Declaring “matching failed” because |SMD| is 0.110.1 is a convention, not a test threshold; whether to worry depends on how strongly that variable acts on the outcome
Reporting mean ± SD for a skewed variableReaders reconstruct a symmetric interval that does not exist; for something like bilirubin, mean − SD can be negative
Printing percentages without missingness countsA shrinking denominator becomes invisible, the commonest way a baseline table misleads
Using imputed values in Table 1 without saying soTable 1 should describe the observed data; imputation belongs to the analysis
Reading an observational Table 1 as “the two groups did not differ”A non-significant test only means this study did not detect a difference, not that the groups are alike — and balance should be judged by SMD, not by a test
Treating a balanced Table 1 as “no confounding left”It covers only the variables you measured; an unmeasured confounder appears in no row at all

Reproducing every number on this page

/opt/homebrew/bin/Rscript figures/scripts/B1-01-table1.R

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 312 randomised patients are duplicated ten times over, giving 3120 rows. Every group mean, standard deviation and distribution shape is unchanged; only the sample size is ten times larger. What happens to the age row?

Show the answer and why

Correct answer: The absolute SMD becomes 0.271, essentially the 0.270 it already was - its denominator depends on spread alone, never on how many people there are

The denominator of an SMD is the root mean square of the two standard deviations, and duplication changes no spread, so 0.270 moves only as far as 0.271, and that sliver comes from the n minus one in the standard deviation. A p value is a different animal: it encodes how large the difference is and how many people there are at once, so after duplication it falls from 0.018 to somewhere past the tenth decimal place. Neither of the other readings survives. The p value does move, and what gets diluted is the information a p value can carry, not the difference itself. A registry study with tens of thousands of patients has a Table 1 significant in every row for exactly this reason.

In the second table (randomised versus registry), the cholesterol row has an empty registry column and no SMD at all. What has happened?

Show the answer and why

Correct answer: All 106 registry patients are missing it - a whole group never measured, so no SMD exists for that cell

The 106 patients who declined randomisation never had the trial blood panel drawn, so the denominator in that cell is zero rather than merely smaller. 28 is the scattered missingness on the randomised side, and 134 is the two added together. Reading 106 as scattered missingness suggests a complete-case analysis could still rescue the comparison; the difference is that a group never measured leaves nothing to compare against. Print percentages without missing counts and the whole thing disappears from the page, and the reader assumes both groups were measured - a quietly shrinking denominator is the commonest way a baseline table misleads. Missingness is often information in its own right: here, not being measured and declining randomisation are two faces of the same fact.

Serum bilirubin has a skewness of 2.70, and the paper reports it in Table 1 as 3.22 plus or minus 4.41 mg/dL. What is wrong with that?

Show the answer and why

Correct answer: Mean minus one standard deviation is -1.19 mg/dL, and bilirubin cannot be negative

A skewness of 2.70 already says the distribution has a long right tail, and mean plus or minus SD implies a symmetric interval: one standard deviation below the mean lands at -1.19 mg/dL, while the smallest value actually observed is positive. The median of 1.40 sitting to the left of the mean of 3.22 is not an error but exactly what right skew looks like - the tail drags the mean and leaves the median where it is. The maximum of 28.00 is not bad data either; bilirubin genuinely reaches those values, and dropping it only hides the skew. The choice is made by looking at the distribution, not by running a normality test first: skewed, bounded or long-tailed quantities such as length of stay, cost, CRP and bilirubin get a median with an interquartile range, and reporting both summaries in Table 1 is perfectly acceptable.

The randomised Table 1 tests 8 variables, and one row comes out below the conventional significance level. How should that be read?

Show the answer and why

Correct answer: If these tests were independent, the chance of at least one significant result across 8 variables is about 0.337, so one of them is entirely expected

0.337 is the chance of at least one significant result across 8 variables; 0.642 belongs to a table with many more variables, the size papers commonly report. Applying the second figure here overstates how likely a chance finding was, though both point the same way: the more variables, the less remarkable one significant row becomes. Baseline variables are usually correlated with each other (age with stage, bilirubin with albumin), so both numbers are order-of-magnitude guides rather than this table's exact probability. As for the row at 0.018, falling below the conventional level does not mean randomisation failed. Under randomisation the null hypothesis that both arms come from one population is true by construction, so any significant result is a type I error by definition. Judge imbalance with the SMD, and never use Table 1 p values to pick covariates for a model - whether to adjust depends on the causal structure, not on which row happened to be imbalanced.

In the randomised table, the sex row has an absolute SMD just over the 0.1 line. How should that be read?

Show the answer and why

Correct answer: The gap between 0.111 and 0.1 means nothing in substance - 0.1 is a convention from the propensity-score literature, not a threshold

The 0.1 line comes from the propensity-score matching literature, where simulations suggested residual imbalance below it usually leaves negligible bias. It is a convention, not a test: nothing separates 0.111 from 0.1 in substance, a looser version also circulates, and a paper must state which line it used. 0.246 really is well above 0.1, but in a randomised trial the two arms can differ only by luck, so Table 1 answers how large the difference is and whether the analysis should adjust for it, not whether randomisation succeeded. Albumin at 0.018 is genuinely balanced, yet a Table 1 entirely inside 0.1 covers only the variables that were measured; an unmeasured confounder appears in no row at all, and treating a balanced Table 1 as proof of no confounding is its own misuse.

The same data, grouped differently: patients who accepted randomisation against those who declined it and agreed only to be followed in the registry. The oedema row has a larger absolute SMD than any row of the randomised table. What does that tell you?

Show the answer and why

Correct answer: 0.393 measures a difference that is really there rather than sampling luck, and this cell measures the size of the confounding

In a randomised comparison the arms can differ only by luck, because allocation has nothing to do with patient characteristics, so a figure like 0.058 answers how far apart this particular draw came out. Group the same people by who accepted randomisation and allocation becomes the patient's own decision: 0.393 now measures a real between-group difference, which is to say the size of the confounding. The p value of 0.014 is no longer meaningless here, since the null is no longer true by construction, but it answers whether a difference exists rather than how large it is, and the second question is what decides whether later adjustment can hold. Data quality is a different row: oedema was recorded in the registry, the blood tests were not. Same data, same variables, different grouping, and the question the table answers has changed completely.

Watch next

用 AI 做臨床研究:做出論文第一張表 Table 1|該不該放 p 值?改用 SMD
繁中Colon & Code· 16 minThe only Traditional Chinese video that tackles the p-value question head on and argues for the SMD instead. It covers exactly what sections three and four of this page do.
AI 臨床研究實戰 EP6|Table 1 基線特徵表怎麼做:p 值的陷阱、常態性檢定、缺失值
繁中Colon & Code· 5 minA five-minute condensed version covering the p-value trap, normality testing and missing values in one go. Good to watch before reading this page.
[R tutorial EP1] How to make baseline characteristics table / Table1
ENBedroom Medicine· 5 minWatch this if you want to see the package produce the whole table in one line — the part this page deliberately does by hand.
Table 1 in R with gtsummary
ENRverse Analytics· 1 minA one-minute demonstration of gtsummary, the other common choice alongside tableone.

Sources and licences

This page is original writing

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.