Bland-Altman plot: agreement between two methods
How to make and read a Bland-Altman plot: bias, limits of agreement with their confidence intervals, a proportional-bias check, sample size and R code.
Updated . Written by Matt Gencer.
On this page
Two instruments, two assays or two observers measure the same quantity on the same samples, and you want to know whether one can replace the other. That is a question about agreement, and neither a correlation coefficient nor a significance test answers it. The Bland-Altman approach (Bland and Altman, 1986) answers it by looking directly at the differences between the two measurements.
The recommended analysis has three parts. Plot each pair’s difference against the mean of the pair. Report the bias (the average difference) and the 95% limits of agreement, each with a confidence interval. Then judge those limits against an acceptable difference that you fixed before looking at the data, because the method cannot say how much disagreement is tolerable. That judgement belongs to the subject-matter question, not to statistics.
This guide covers the whole workflow: what the plot shows, how each number is computed, how precise the limits are, how to check whether the bias changes across the measurement range, how many pairs a study needs, what to do when the basic analysis does not fit, and what to report. A worked example on 60 synthetic pairs, run through the Celeus engine with its R script, carries the numbers throughout.
What a Bland-Altman plot shows
Each point is one sample or subject measured by both methods. The horizontal axis is the mean of the two measurements, the best available estimate of the true value. The vertical axis is their difference, always taken in the same direction, for example new method minus reference. Three horizontal lines summarise the picture: the mean difference (the bias), and a line above and below it marking the limits of agreement.
The plot answers questions that a single number cannot:
- Is the cloud of differences centred on zero, or does one method read systematically higher?
- Does the scatter stay about the same across the measurement range, or fan out at high values?
- Do the differences drift upward or downward as the magnitude increases?
- Are there isolated points far from the rest, and are they real disagreements or recording errors?
The horizontal axis is the pair mean and not either method’s own value. If you plot the difference against one method, a spurious relationship appears even for two methods that agree on average, because that method’s measurement error is part of both axes. Plotting against the mean avoids this, and Bland and Altman discuss the pitfall of plotting the difference against one variable only (Bland and Altman, 2003). A method called a gold standard still carries measurement error of its own, so the same reasoning applies.
Common variations keep this layout. Shaded bands can show the confidence interval around the bias and each limit, and the vertical axis can be a percentage difference or a log-scale ratio when the scatter grows with the magnitude (see the section on when the basic analysis does not fit). Which method is subtracted from which only changes the sign of the bias and of both limits (the lower limit becomes minus the upper one); the width of the limits and the conclusion do not change, as long as the report states the direction.
The calculation, step by step
The basic analysis needs nothing beyond a mean and a standard deviation.
- For each pair, compute the difference, first method minus second. Keep the direction fixed and say which way round it is when you report the result.
- The bias is the mean of those differences. A positive bias means the first method reads higher on average.
- The standard deviation of the differences (often written s) describes how much the disagreement varies from one sample to the next. It is the standard deviation of the differences themselves, not of either method’s readings.
- The 95% limits of agreement are the bias minus and plus 1.96 times s.
If the differences are roughly normal and their spread does not depend on the magnitude, about 95% of future differences between the two methods on similar samples should fall inside the limits (Bland and Altman, 1999). Some texts round 1.96 to 2, as the original 1986 paper did; the difference is small and either is acceptable as long as the report says which was used.
The limits describe individual disagreement, which is what matters when one method is to replace the other on a single sample. The bias alone describes only the average, and two methods can have a bias of exactly zero while disagreeing by large amounts on every sample, in both directions.
Confidence intervals for the bias and the limits
Both the bias and the limits are estimates from a sample, and a different set of samples would give different values. Reporting them without intervals gives a false sense of precision, and Bland and Altman (1999) give confidence intervals for both.
The interval for the bias is the familiar t-based interval for a mean: the bias plus or minus the t critical value times s divided by the square root of the number of pairs. It is the same interval a paired t-test reports for the mean difference.
Each limit of agreement has its own interval, and it is wider than the interval for the bias, because a limit depends on the estimated standard deviation as well as the estimated mean. The approximate standard error of a limit is s times the square root of (1/n + 1.96² / (2(n - 1))), where n is the number of pairs. The interval is the limit plus or minus the t critical value times that standard error. For large n this standard error is close to s times the square root of 3/n.
That approximation is what most software, including Celeus, reports. Carkeet (2015) derived exact intervals under the same normality assumption and showed that they can differ considerably from the approximate ones when the sample is not large. With a few dozen pairs or more the approximation is usually adequate for reporting; with very few pairs, treat the approximate interval as a rough guide and consider the exact method.
The limits say where most individual differences fall; the intervals say how well the study has pinned those limits down. A study can have narrow limits that are poorly estimated, or wide limits that are estimated precisely, so the report needs both.
Setting the acceptable difference before you look
The acceptable difference is a scientific or practical decision, not a statistical output. It might come from the known biological variation of the quantity, from a laboratory or regulatory tolerance for the assay, from the resolution of the instrument, or from the smallest difference that would change a decision based on the measurement. Giavarina (2015) stresses that the Bland-Altman analysis defines the interval of agreement but does not say whether it is acceptable, and that acceptable limits must be set a priori.
Write the threshold down before the comparison, together with who set it and why. A threshold chosen after seeing the limits tends to be just wide enough to contain them, which defeats the purpose. A review of method comparison reports found that an a priori decision on acceptable limits and an estimate of the precision of the limits were often missing (Abu-Arafeh and colleagues, 2016), so stating both is the single most useful thing a report can do.
There are two common ways to use the threshold. The lenient reading asks whether the limits of agreement themselves lie inside the acceptable range. The stricter reading asks whether the outer end of each limit’s confidence interval lies inside it, so that the conclusion holds even allowing for the uncertainty in the limits. Choose which one you will use when you set the threshold, not afterwards. Neither reading is the correct one in general; the choice depends on what the comparison is meant to decide and how costly a wrong conclusion would be.
One refinement applies to the stricter reading. The usual intervals treat each limit separately, and Carkeet (2015) notes that intervals for the two limits considered as a pair are appropriate for most situations, with the individual intervals suited to some. The intervals in this guide, and the ones Celeus reports, are the individual approximate ones, so say so in the report when you apply the stricter reading to them.
Why correlation and a paired t-test are not enough
Correlation measures how well one set of values predicts the other, not whether they are the same. If a device reads exactly twice the reference value on every sample, the correlation is perfect and the agreement is terrible. A high correlation is also easy to get simply because the samples span a wide range: correlation depends on the range of the true quantity in the sample, and a wide range pushes it up whatever the measurement error is (Bland and Altman, 1986). Giavarina (2015) does not recommend correlation for judging whether two methods are comparable.
Regressing one method on the other has a related problem, and Bland and Altman (2003) describe how correlation and regression are misapplied in measurement studies. A slope of 1 and an intercept of 0 are consistent with agreement, but the regression says nothing direct about how far apart individual readings are. There is also a structural problem: ordinary least squares is built on the assumption that the predictor is measured without error, and when both variables are measurement methods that assumption cannot hold, so the fitted slope is pulled toward zero.
A paired t-test asks something narrower: is the average difference zero? A non-significant result says nothing about the spread. Conversely, in a large sample a trivial constant offset will be statistically significant yet harmless. Bland and Altman (2003) stress that agreement is a question of estimation, not of significance testing. The test of bias is a useful check, but agreement is judged from the bias, the limits and their intervals against the threshold.
Worked example: a portable analyser against a reference
A laboratory wants to know whether a portable analyser can stand in for its bench reference analyser. Sixty samples spanning a wide range of concentrations are each measured once by both instruments. The data here are synthetic: they were generated in R with a fixed seed, with each instrument adding its own independent random error to a true value and the portable analyser set to read 2 units higher on average. No real samples or participants are involved, and the example is about the method, not about any instrument.
The design is paired: every sample is measured by both methods, so the unit of analysis is the pair, and the 60 pairs are independent of each other because each sample appears once. The outcome is a continuous measurement and nothing is censored. Differences are portable minus reference.
For this example, we fixed the criterion before the engine run: differences of up to 10 units in either direction count as acceptable, and the stricter reading applies, so the confidence interval of each limit must stay inside that range. Both choices belong to the example. The value 10 is a round number picked to illustrate the method, not a recommended tolerance for any real analyte or instrument; in a real study it would come from the sources described above, set by the people who will use the measurement.
The Celeus engine ran the Bland-Altman analysis on the 60 pairs:
| Quantity | Value |
|---|---|
| Pairs | 60 |
| Bias (mean difference, portable minus reference) | 2.32 (95% CI 1.27 to 3.37) |
| SD of the differences | 4.07 |
| Lower limit of agreement | -5.66 (95% CI -7.46 to -3.85) |
| Upper limit of agreement | 10.30 (95% CI 8.49 to 12.11) |
| Paired t-test of bias = 0 | t(59) = 4.42, p < 0.001 |
| Normality of the differences (Shapiro-Wilk) | W = 0.99, p = 0.96 |
Reading the bias
The portable analyser reads higher than the reference by 2.32 units on average, and the interval from 1.27 to 3.37 excludes zero. The paired t-test agrees: the average difference is unlikely to be zero, given these data. Because the data were generated with a true offset of 2 units, you can see that the interval does contain the value it is estimating, which is what a 95% interval should do in most samples, though never with certainty in any one.
On its own, the significant test says only that there is a systematic offset. It says nothing about whether the offset matters, and nothing about how far apart readings on individual samples will be.
Reading the limits
The limits of agreement run from -5.66 to 10.30. For a new sample of the same kind, the portable analyser can be expected to read anywhere from about 5.7 units below the reference to about 10.3 above it, in about 95% of cases.
Against the example’s threshold of 10 units, the lower limit is comfortably inside, but the upper limit already sits just beyond it, and its confidence interval reaches 12.11. Under the stricter reading fixed in advance, the portable analyser does not meet the example’s agreement criterion, so on these data it should not be treated as interchangeable with the reference. Under the lenient reading the conclusion is the same, only less clear-cut, since the upper limit itself sits just outside the threshold.
The numbers also show where the problem comes from. The limits are not centred on zero, because the bias shifts both of them up by 2.32 units. The random part of the disagreement, 1.96 times the SD of the differences, is about 7.98 units on either side of the bias, and that alone would fit inside a 10-unit range; it is the offset added on top that pushes the upper limit past it. If the offset is stable across the range, the next step a laboratory would consider is recalibrating the portable analyser and then checking the recalibrated instrument on a fresh set of samples. Subtracting the observed bias from the same data and re-analysing them would only confirm the arithmetic, not the recalibration.
Reading the assumption output
The engine checks the differences for normality with a Shapiro-Wilk test and reported W = 0.99 with p = 0.96. That means the test did not detect a departure from normality in these 60 differences. It is not evidence that the differences are normal; with few pairs the test has little power, and with many pairs it flags departures too small to matter. The plot, and a histogram of the differences, matter more than the test.
The engine’s sample-size check also passed. That check is a floor on the number of pairs, not a judgement that the limits are precise enough for your purpose; the confidence intervals above are what tell you that.
The analysis also assumes that the bias and the spread are the same across the measurement range. The next section checks the first of these.
Checking for proportional bias
A constant offset moves every point up or down by the same amount. A proportional bias is different: the difference between the methods grows or shrinks with the size of the measurement, so the points slope across the plot. When that happens, a single bias and a single pair of limits for the whole range are misleading, because the agreement at the low end is not the agreement at the high end.
The simplest check is to regress the differences on the pair means and look at the slope. A slope near zero is what you would see with no proportional bias. This regression of difference on mean is the basis of the more general regression approach to limits of agreement that Bland and Altman (1999) describe for data where the difference is related to the magnitude.
For the worked example, a companion engine run regressed the 60 differences on the 60 pair means:
| Quantity | Value |
|---|---|
| Slope of difference on pair mean | 0.028 (95% CI -0.003 to 0.059) |
| Test of slope = 0 | t = 1.78 on 58 degrees of freedom, p = 0.08 |
| R² | 0.05 |
The slope is small, and its interval includes zero, so this check did not detect a proportional bias. That is not the same as showing there is none. The upper end of the interval corresponds to a difference that would change by several units between the lowest and highest samples, and these data cannot rule that out. The pair mean explains about 5% of the variation in the differences, which also says that most of the disagreement is not explained by magnitude.
In practice, read the slope together with the plot. If the points fan out or tilt, act on that even when the test of the slope is not significant, and if the slope is clearly non-zero, one bias for the whole range should not be reported as if it applied everywhere. Celeus does not run this check automatically; the companion run here uses its ordinary linear regression on the differences and pair means.
Regression-based limits when the bias does change
When the slope is clearly non-zero, or the spread grows with the magnitude, Bland and Altman (1999) describe limits that follow the data instead of staying flat. The procedure takes three steps:
- Regress the differences on the pair means. The fitted line is the bias at each magnitude.
- Take the residuals from that line, drop their signs, and regress the absolute residuals on the pair means. That second line tracks how the typical size of the disagreement changes.
- Turn the second line into a standard deviation by multiplying it by the square root of π/2, about 1.25, because for normally distributed residuals the mean absolute value is the standard deviation times the square root of 2/π. The limits are the first line plus and minus 1.96 times that standard deviation, which works out to about 2.46 times the fitted absolute residual.
The result is a pair of lines that widen or narrow across the range, and the report then gives the two regression equations instead of two single numbers. Use it only when the plot shows a real trend; for the worked example, where the check did not detect one, the flat limits above remain the main summary, with the caveat that a modest slope was not ruled out. The R code for this approach is in the section on running the analysis below.
When the basic analysis does not fit
The simple analysis rests on assumptions, and the plot is where you check them. Bland and Altman (1999) extend the method for each of the common failures.
- Spread or bias that grows with the magnitude. If the scatter fans out toward higher means, or the points slope, a log transformation of both measurements is the usual first remedy. The analysis is then done on the log scale, and the limits, transformed back, are expressed as ratios of one method to the other. Plotting percentage differences against the mean is a related option (Giavarina, 2015). When neither works, the regression approach models the bias and the spread as functions of the magnitude and gives limits that change across the range.
- Non-normal differences. The 1.96 multiplier assumes roughly normal differences. With a skewed distribution or heavy tails, a nonparametric approach is an alternative (Bland and Altman, 1999). Expect it to need more pairs: limits read directly from the 2.5th and 97.5th percentiles of the observed differences rest on the few most extreme values, while limits built from a standard deviation use every pair, so the percentile limits are less precise for the same number of pairs when the differences are close to normal.
- Repeated measurements on the same subject. The basic formula treats pairs as independent. Several pairs per subject make the limits too narrow, because the subjects, not the pairs, are the independent units. Bland and Altman (2007) give methods for these clustered data, both when the true value is stable within a subject and when it changes between measurements.
- Poor repeatability of either method. If one method does not agree with itself, it cannot agree well with anything else. Where replicate measurements are available, Bland and Altman (1999) recommend estimating each method’s repeatability separately and comparing it with the limits of agreement.
- Outliers. A single extreme difference can widen the limits a great deal. Check it against the records first. If it is a genuine disagreement, it is part of what the study found and should stay in; report the analysis with and without it only if you also say why.
How many pairs do you need
The number of pairs governs how precisely the limits of agreement are estimated, so plan it around the width of the interval around each limit that you can tolerate. The planning rule follows from the standard error above. Bland and Altman (1986) give the standard error of each limit as about √(3s²/n), that is s × √(3/n), where s is the standard deviation of the differences and n is the number of pairs. For a reasonably large study, the 95% interval around each limit therefore extends about 1.96 × s × √(3/n) on either side of it; the 1986 paper rounds the multiplier to 2.
Two practical consequences follow. First, the precision depends on the square root of n, so halving the width of the interval takes four times as many pairs. Second, if you express the acceptable half-width w as a multiple of s, the rule rearranges to n ≈ 3 × 1.96² / w², about 11.5 / w², which is usually rounded up to n ≈ 12 / w² (exactly the figure the rounded multiplier of 2 gives). You need a value of s to turn that into units, and it should come from a pilot study, from the instruments’ published precision or from earlier comparisons, not from the data of the study you are planning. The rule is an approximation for moderately large n; in small studies the exact intervals of Carkeet (2015) can differ considerably from it.
A precision target is not the only way to plan. Lu and colleagues (2016) derived a sample-size method that sets the number of pairs so that the confidence intervals of the limits are likely to fall inside a predefined acceptable limit, given an assumed bias and standard deviation of the differences and chosen error rates. Their approach suits a study whose conclusion will be the stricter reading described earlier.
If the number of pairs is fixed in advance by cost or by the samples available, compute the expected interval width before the study, and say in the report when precision was limited.
Running it in R
The calculation needs only base R. Here a and b are the two methods’ readings, one row per sample, with any incomplete pairs removed.
d <- a - b # first method minus second
n <- length(d)
bias <- mean(d)
s <- sd(d)
loa <- bias + c(-1, 1) * 1.96 * s
tc <- qt(0.975, df = n - 1)
bias_ci <- bias + c(-1, 1) * tc * s / sqrt(n)
se_loa <- s * sqrt(1 / n + 1.96^2 / (2 * (n - 1)))
lower_ci <- loa[1] + c(-1, 1) * tc * se_loa
upper_ci <- loa[2] + c(-1, 1) * tc * se_loa
t.test(a, b, paired = TRUE) # test of bias = 0
shapiro.test(d) # normality check on the differences
The plot and the proportional-bias check take a few more lines:
m <- (a + b) / 2
plot(m, d, xlab = "Mean of the two methods", ylab = "Difference (first minus second)")
abline(h = bias, lty = 1)
abline(h = loa, lty = 2)
summary(lm(d ~ m)) # slope of difference on mean
confint(lm(d ~ m))
If the plot shows a real trend, the regression-based limits described earlier follow from two fits:
fit_bias <- lm(d ~ m) # bias as a function of magnitude
fit_abs <- lm(abs(resid(fit_bias)) ~ m) # size of disagreement vs magnitude
sd_m <- sqrt(pi / 2) * fitted(fit_abs) # mean |residual| converted to an SD
lower <- fitted(fit_bias) - 1.96 * sd_m
upper <- fitted(fit_bias) + 1.96 * sd_m
ord <- order(m)
plot(m, d, xlab = "Mean of the two methods", ylab = "Difference (first minus second)")
lines(m[ord], fitted(fit_bias)[ord])
lines(m[ord], lower[ord], lty = 2)
lines(m[ord], upper[ord], lty = 2)
The worked example’s own R script is shown below this guide, exactly as the engine generated it, with the seed and the output it printed. It expects the 60 synthetic pairs in a data/ file beside it, which this page does not offer for download, and from them it recomputes the bias, the standard deviation of the differences, the limits, their intervals and the paired-test p-value; before publication, a rerun of the script was checked against the recorded p-value. It does not recompute the normality check or the sample-size check, and it does not cover the proportional-bias regression, which came from a separate engine run on the same generated data.
What to report
Reporting advice for method comparison studies is scattered, and Abu-Arafeh and colleagues (2016) assembled it into a list of key features. A report that covers the following lets a reader judge agreement without guessing:
- The question: which methods, which quantity, and what the comparison is meant to decide.
- The acceptable difference, who set it, why, and whether it was set before the data were seen.
- The number of pairs, how the samples were chosen, and the range of values they cover.
- The data structure: one pair per subject, or repeated measurements, and how repeats were handled.
- The direction of the difference: which method was subtracted from which.
- The bias with its 95% confidence interval.
- The standard deviation of the differences and the 95% limits of agreement, each with its confidence interval, and how the intervals were computed.
- The plot, with the bias and limits drawn on it.
- What was done about any relationship between difference and magnitude, non-normal differences or outliers.
- The conclusion, stated against the pre-set threshold.
A sentence for the worked example might read: “Across 60 samples, the portable analyser read on average 2.32 units higher than the reference (95% CI 1.27 to 3.37). The 95% limits of agreement were -5.66 (95% CI -7.46 to -3.85) to 10.30 (95% CI 8.49 to 12.11). The upper limit’s confidence interval exceeded the pre-specified acceptable difference of 10 units, so the analyser did not meet the agreement criterion.”
Common mistakes
- Reporting a correlation as evidence of agreement. It measures association, not agreement, and is inflated by a wide range of values.
- Deciding the threshold after seeing the limits. The result then confirms whatever was found.
- Reporting the limits without their confidence intervals. In small studies the limits are uncertain enough to change the conclusion.
- Treating a non-significant bias test as proof of agreement. It says nothing about the spread, and absence of evidence of bias is not evidence of no bias.
- Ignoring a trend or a fan in the plot. One pair of limits for the whole range hides worse agreement at one end.
- Pooling repeated measurements as if they were independent. The limits come out too narrow.
- Plotting the difference against one method. That builds a spurious slope into the picture.
Agreement, reliability or accuracy: which question are you asking?
Several study designs compare measurements, and they are easy to confuse because they all involve two sets of readings on the same samples. Naming the question first picks the method.
- Agreement between two methods on a continuous scale. Can one method replace the other on an individual sample? That is the Bland-Altman question, answered with the bias, the limits of agreement and a pre-set tolerance, as in this guide.
- Reliability between raters or occasions. Do different observers, or the same observer on different days, give consistent readings? For continuous scores this is commonly summarised with an intraclass correlation coefficient, and for categories with kappa or one of its alternatives. An intraclass correlation is, by construction, the share of the total variation that comes from real differences between subjects, so the same measurement error gives a higher coefficient in a more varied sample and a lower one in a more uniform sample. That is why it answers a different question from limits of agreement, which are expressed in the measurement’s own units and do not reward a wide spread of subjects. The two can usefully be reported together.
- Diagnostic accuracy against a reference standard. Does a test or score correctly classify subjects whose true status is known from a reference standard? That calls for sensitivity, specificity and predictive values for a fixed cut-off, or an ROC curve and its area for a continuous score. A Bland-Altman analysis would be the wrong tool there, because the reference is a category, not a measurement on the same scale.
- Calibration of one method against another. Is the relationship between two methods a straight line with a known slope and intercept, so that one can be converted into the other? That is a regression question. Because both methods carry measurement error, a regression that allows for error in both variables, such as Deming or Passing-Bablok regression, fits the question better than ordinary least squares, which, as noted earlier, assumes the predictor is exact.
A single study can contain more than one of these questions, each answered with its own method and its own pre-set criterion.
Related guides
Agreement sits next to several other questions that look similar and need different methods. If the question is whether a paired mean difference is zero rather than whether two methods agree, the comparison of the paired t-test and the Wilcoxon signed-rank test covers it. For repeated measurements over time on the same subjects, see repeated-measures ANOVA versus a mixed model. For choosing among methods in general, start from choosing a statistical test, and for what makes an analysis reproducible, see reproducible statistical analysis. The Bland-Altman method reference lists exactly what Celeus computes, and the linear regression reference covers the model used for the proportional-bias check.
How Celeus handles this
Given two numeric columns, Celeus takes the difference as the first column minus the second and reports the bias with its confidence interval, the standard deviation of the differences, the 95% limits of agreement with a confidence interval on each (the approximate Bland-Altman intervals described above), and a paired t-test of whether the bias is zero. It checks the differences for normality and the sample size, requires at least three complete pairs, and draws the plot with differences against pair means, a solid line at the bias and dashed lines at the limits. Every run comes with an R script that reproduces it.
Celeus does not currently test for proportional bias, offer a log or ratio version, or handle repeated measurements per subject. Inspect the plot, run the regression of difference on mean as shown above when you need the check, and use the methods cited here when your data need them. The acceptable difference is always yours to set.
Worked example
Data: synthetic, generated in the script below. Seed: 20261022.
Run on Celeus engine 0.30.0, seed 20261022, synthetic data.
Output
# Results - Test: Bland-Altman agreement - n: 60 - statistic: 4.419 - p-value: < 0.001 - effect size: mean difference (bias) = 2.322 (95% CI 1.27 to 3.373) - 95% CI: [1.27, 3.373] - seed: 20261022 ## Assumption checks - normality (Shapiro-Wilk): passed=TRUE (no evidence against normality) - sample size: passed=TRUE (adequate n) ## Power - Power is not calculated for this test.
R script
# Celeus - reproduce.R (run from this package folder; bundled data in data/)
# Test: Bland-Altman agreement | engine 0.30.0 | catalog c39-d3cd
# Research context: not provided for this run.
# Reproduces the recorded result deterministically.
set.seed(20261022)
.data_path <- "data/bland-altman-agreement.csv"
if (!file.exists(.data_path)) stop("Run reproduce.R from the package folder (the bundled data is in data/).")
data <- readr::read_csv(.data_path, show_col_types = FALSE) # needs the readr package
clean_cells <- function (df)
{
ctrl_collapse <- "[\r\n\t\v\f]+"
zero_width_chars <- intToUtf8(c(8203L, 65279L), multiple = TRUE)
uni_space_chars <- intToUtf8(c(160L, 8239L, 8199L), multiple = TRUE)
clean_text <- function(x) {
out <- x
for (ch in zero_width_chars) out <- gsub(ch, "", out,
fixed = TRUE)
out <- gsub(ctrl_collapse, " ", out)
for (ch in uni_space_chars) out <- gsub(ch, " ", out,
fixed = TRUE)
trimws(gsub(" +", " ", out))
}
changed_cols <- character(0)
cells_cleaned <- 0L
retyped <- character(0)
for (j in seq_along(df)) {
col <- df[[j]]
if (!is.character(col))
next
cleaned <- clean_text(col)
n_changed <- sum(!is.na(col) & !is.na(cleaned) & col !=
cleaned, na.rm = TRUE)
if (n_changed > 0L) {
changed_cols <- c(changed_cols, names(df)[j])
cells_cleaned <- cells_cleaned + n_changed
}
df[[j]] <- cleaned
non_blank <- cleaned[!is.na(cleaned) & nzchar(cleaned)]
if (length(non_blank) && all(grepl("^[+-]?(0|[1-9][0-9]*)([.][0-9]+)?$",
non_blank))) {
parsed <- suppressWarnings(as.numeric(cleaned))
was_blank <- is.na(cleaned) | !nzchar(cleaned)
lost <- (is.na(parsed) | is.infinite(parsed)) & !was_blank
if (!any(lost)) {
finite <- parsed[!is.na(parsed)]
all_whole <- all(finite == floor(finite))
in_range <- all(abs(finite) <= .Machine$integer.max)
df[[j]] <- if (all_whole && in_range)
as.integer(parsed)
else parsed
retyped <- c(retyped, names(df)[j])
}
}
}
names(df) <- clean_text(names(df))
if (length(changed_cols)) {
attr(df, "ingest_clean_columns") <- changed_cols
attr(df, "ingest_clean_cells_cleaned") <- cells_cleaned
}
if (length(retyped))
attr(df, "ingest_clean_retyped") <- retyped
df
}
data <- clean_cells(data)
# Complete-case analysis: drop rows missing any analysis value.
.acols <- c("portable", "reference")
data <- data[stats::complete.cases(data[, .acols, drop = FALSE]), , drop = FALSE]
result <- { .d <- data[["portable"]] - data[["reference"]]; .d <- .d[!is.na(.d)]; .n <- length(.d); .bias <- mean(.d); .sd <- stats::sd(.d); .k <- 1.96; .lo <- .bias - .k * .sd; .hi <- .bias + .k * .sd; .tc <- stats::qt(1 - (1 - 0.95) / 2, df = .n - 1); .se <- .sd / sqrt(.n); .se_loa <- .sd * sqrt(1 / .n + .k^2 / (2 * (.n - 1))); list(bias = .bias, sd = .sd, loa = c(.lo, .hi), bias_ci = c(.bias - .tc * .se, .bias + .tc * .se), loa_lower_ci = c(.lo - .tc * .se_loa, .lo + .tc * .se_loa), loa_upper_ci = c(.hi - .tc * .se_loa, .hi + .tc * .se_loa), p_value = stats::t.test(data[["portable"]], data[["reference"]], paired = TRUE)$p.value) }
print(result)Common questions
What is a Bland-Altman plot?
It is a scatter plot for comparing two methods that measure the same quantity on the same samples. Each point is one sample, with the difference between the two readings on the vertical axis and their mean on the horizontal axis. Lines mark the average difference (the bias) and the 95% limits of agreement.
How do you interpret the limits of agreement?
If the differences are roughly normal and stable across the range, about 95% of differences between the two methods on new samples of the same kind should fall between the two limits. Compare the limits, and their confidence intervals, with a largest acceptable difference that you fixed before the study.
Can I use a correlation coefficient instead of a Bland-Altman plot?
No. Correlation measures whether the two methods rise and fall together, not whether they give the same values. A method that reads every sample at double the true value correlates perfectly with the reference and agrees badly, and a wide range of samples inflates the correlation whatever the measurement error.
How many samples do I need for a Bland-Altman analysis?
Plan the number of pairs around how precisely you need the limits of agreement. The confidence interval around each limit shrinks with the square root of the number of pairs, so halving its width takes four times as many pairs. Small studies give limits too uncertain to judge against a tolerance.
Does a significant paired t-test mean the two methods disagree?
Not on its own. The test only asks whether the average difference is zero. With many pairs, a small constant offset that nobody would care about becomes significant, and with few pairs a large one can be missed. Judge agreement from the bias and the limits against a pre-set tolerance.
What share of points should fall outside the limits of agreement?
About 5% on average, if the differences are roughly normal and stable across the range, because the limits are built to contain about 95% of differences. In any one study the count outside varies by chance, especially with few pairs, so a few more or fewer than 5% is not a problem in itself. Many points outside, or outside points bunched at one end of the range, are a reason to look again at the plot.
Do the measurements or the differences need to be normal?
The differences. The 1.96 multiplier in the limits assumes the differences are roughly normal, and the measurements themselves can have any distribution. Check a histogram of the differences and the plot; if they are skewed or the spread grows with the magnitude, a log transformation or a nonparametric approach is the usual alternative.
What if my mean bias is near zero but the limits of agreement are wide?
Then the methods agree on average but not on individual samples. The bias describes only the average, so two methods can have a bias of zero and still differ by large amounts in both directions. Judge the limits, with their confidence intervals, against the acceptable difference you fixed in advance.
What should I do if the plot looks bad?
Find out why before changing the analysis. A tilt means the bias depends on the magnitude, a fan means the spread does, and isolated far points may be recording errors. Check those points against the records, consider a log scale or regression-based limits, and report the limits as they are if the methods do not meet the threshold.
Sources
- Bland JM, Altman DG (1986). Statistical methods for assessing agreement between two methods of clinical measurement. The Lancet 327(8476):307-310. doi:10.1016/S0140-6736(86)90837-8
- Bland JM, Altman DG (1999). Measuring agreement in method comparison studies. Statistical Methods in Medical Research 8(2):135-160. doi:10.1177/096228029900800204
- Bland JM, Altman DG (2003). Applying the right statistics: analyses of measurement studies. Ultrasound in Obstetrics and Gynecology 22(1):85-93. doi:10.1002/uog.122
- Bland JM, Altman DG (2007). Agreement between methods of measurement with multiple observations per individual. Journal of Biopharmaceutical Statistics 17(4):571-582. doi:10.1080/10543400701329422
- Giavarina D (2015). Understanding Bland Altman analysis. Biochemia Medica 25(2):141-151. doi:10.11613/BM.2015.015
- Carkeet A (2015). Exact parametric confidence intervals for Bland-Altman limits of agreement. Optometry and Vision Science 92(3):e71-e80. doi:10.1097/OPX.0000000000000513
- Lu MJ, Zhong WH, Liu YX, Miao HZ, Li YC, Ji MH (2016). Sample size for assessing agreement between two methods of measurement by Bland-Altman method. The International Journal of Biostatistics 12(2). doi:10.1515/ijb-2015-0039
- Abu-Arafeh A, Jordan H, Drummond G (2016). Reporting of method comparison studies: a review of advice, an assessment of current practice, and specific suggestions for future reports. British Journal of Anaesthesia 117(5):569-575. doi:10.1093/bja/aew320
Methods discussed
Try it on your own data
Upload a dataset and Celeus suggests a method, checks its assumptions, runs it in R, and gives you the script to rerun it.
Try it in Celeus