*! version 1.1 2023-09-27 Mark Chatfield

Title

blandaltman -- Bland-Altman plots featuring differences or %differences or ratios, with options to add a variety of lines and intervals

Syntax

blandaltman varA varB [if] [in],
plot(plot_type_list)
[horizontal
noregloa
noregbias
hloa
hbias
level(#)
predinterval
ticonfidence(#)
ticonfidence2(#)
ticonfidence3(#)
ciloa
cibias
cilevel(#)
minor_options]

where plot_type_list is any combination of plot_types:

plot_type

difference A-B is plotted on the y-axis, Mean(A,B) on the x-axis

percentmean 100(A-B)/Mean(A,B) is plotted on the y-axis, Mean(A,B) on the x-axis

percentlmean 100(A-B)/LMean(A,B) = 100(lnA-lnB) is plotted on the y-axis, GMean(A,B) on the x-axis*

ratio A/B is plotted on the y-axis, GMean(A,B) on the x-axis*

*When A>0 and B>0, GMean(A,B) = sqrt(A*B) is the Geometric Mean,
and LMean(A,B) = (A-B)/(lnA-lnB) is the Logarithmic Mean (LMean(A,B) = A if A=B)

options

Main
horizontal display horizontal rather than regression-based limits of agreement and bias.
Equivalent to specifying: noregloa noregbias hloa hbias

noregloa prevent display of regression-based limits of agreement

noregbias prevent display of regression-based bias and limits of agreement

hloa display horizontal limits of agreement

hbias display horizontal bias (i.e. average difference or %difference or ratio).
This option is assumed whenever horizontal limits of agreements or a prediction interval or a tolerance interval is requested.

level(#) specifies the level, in percent, for #% limits of agreement,
#% prediction interval, #% tolerance interval with ticonf% confidence. The default is level(95).

predinterval display (horizontal) lines for a level% prediction interval

ticonfidence(#) display (horizontal) lines for a level% tolerance interval with #% confidence

ticonfidence2(#) display (horizontal) lines for a second level% tolerance interval with #% confidence

ticonfidence3(#) display (horizontal) lines for a third level% tolerance interval with #% confidence

ciloa display (exact) cilevel% confidence intervals for the (horizontal) limits of agreement.
Requires horizontal or hloa to also be specified.

cibias display a cilevel% confidence interval for the (horizontal) bias.
Requires horizontal or hbias to also be specified.

cilevel(#) specifies the level, in percent, for confidence intervals for the bias and limits of agreement.
The default is cilevel(95).

Minor

scopts(scatter_options) alter the display of the scatterplot

regloaopts(tw_function_options) alter the display of the regression-based limits of agreement

regbiasopts(tw_function_options) alter the display of the regression line

loaopts(tw_function_options) alter the display of the horizontal limits of agreement

biasopts(tw_function_options) alter the display of the horizontal bias line

piopts(tw_function_options) alter the display of the prediction interval

tiopts(tw_function_options) alter the display of the first tolerance interval

tiopts2(tw_function_options) alter the display of the second tolerance interval

tiopts3(tw_function_options) alter the display of the third tolerance interval

ciloaopts(tw_pcarrowi_options) alter the display of the confidence interval for the limits of agreement

cibiasopts(tw_pcarrowi_options) alter the display of the confidence interval for the bias

addplot(plot ... [|| plot ... [...]]) plot may be any subcommand of graph twoway, such as function

twoway_options titles, legends, axes, added lines and text, regions, name, aspect ratio, etc.
by() warning: any lines, intervals and stats are NOT calculated separately for each subset

Description

As described in Chatfield et al. (2023), blandaltman produces Bland-Altman plots featuring
(a) difference, (b) percentage difference or (c) ratio on the y-axis,
and (arithmetic or geometric) mean on the x-axis.
By default, regression-based bias and limits of agreement are produced in order to help everyone
see how the distribution of (a), (b) or (c) varies with the average of the paired measurements
(this is a key purpose of a Bland-Altman plot).
Horizontal lines for bias and limits of agreement can be produced instead.

This is the first community-contributed Bland-Altman plot command in Stata allowing display of
confidence intervals for the bias and limits of agreement,
as well as a prediction interval and (up to 3) tolerance intervals,
assuming the distribution of (a), (b) or log (c) is normal and has no relationship with the magnitude of the measurements.

Logarithmically-scaled axes are used (i) for both axes when ratios are plotted against the geometric mean,
(ii) for the x-axis when percentage differences are plotted against the (arithmetic or geometric) mean.

Remarks

The following 3 plots are equivalent (they differ only in their axis labelling):

. blandaltman lnvarA lnvarB, plot(difference)

. blandaltman varA varB, plot(ratio)

. blandaltman varA varB, plot(percentlmean)

For more on percentlmean see Chatfield et al. (2023),
and references therein.

The following plot will often be very similar (this plot is commonly used with lab measures)

. blandaltman varA varB, plot(percentmean)

Bland and Altman (1999) described a regression-based approach to describe the bias and 95% limits of agreement
on a plot of difference (A-B) against the mean of the paired measurements.
Their method has been adapted for plots featuring percentage differences or ratios:

percentmean ... the first regression is %difference on ln(Mean(A,B))

percentlmean ... the first regression is %difference on ln(GMean(A,B))

ratio ... the first regression is ln(A/B) on ln(GMean(A,B))

The first regression equation can be interpreted as an equation for the Bias
of difference or %difference or ln(A/B).
After the first regression, residuals are calculated, their absolute values taken,
then adjusted by multiplying by sqrt(_pi/2). A second regression then takes place using
these adjusted absolute residuals. This allows the resulting regression equation
to be interpreted as an equation for the SD of difference or %difference or ln(A/B).
Equations for 95% LoA are then: Bias_equation ± 1.96 SD_equation.
Note an equation lnR = b0 + b1 × ln(GMean(A,B)) can be re-written as R = exp(b0) × GMean(A,B)^b1.

As well as reporting limits of agreement, Bland and Altman (1999) proposed
calculating a 95% CI around each of the 95% limits of agreement
and this advice features in reporting standards for Bland-Altman agreement analysis (Gerke 2020).
While Bland and Altman described how to calculate approximate 95% CIs,
there exists an exact method based on the noncentral t distribution
(Carkeet 2015, Meeker et al. 2017, Shieh 2018) which is implemented here.
It is an oversight of [R] centile that this exact method is not available.
The 2021 revision of the tolerance command (ssc install tolerance)
calculates CIs for the limits of agreement (i.e. 2.5th and 97.5th normal percentiles),
as well as prediction and tolerance intervals.

Some authors have disagreed with some of Bland and Altman's recommendations, and
have recommended that prediction intervals and tolerance intervals be used
(Ludbrook 2010, Vock 2016, Carkeet and Goh 2018, Francq, Berger and Boachie 2020),
though their recommendations vary quite a bit.
Royston and Matthews (1991) considered all these for how to best estimate a 95% reference range from a normal sample -
they favoured mean ± 1.96 sd, the same as Bland and Altman.

A 95% prediction interval is an interval where a future measurement is expected to lie, with a given confidence level
(Meeker et al. 2017, Vardeman 1992). It is equivalent to a 95%-expectation tolerance interval,
which is an interval that contains 95% of the population, on average.

A 95% tolerance interval with #% confidence is an interval that contains at least 95% of a population, with #% confidence (Vangel 2005, Vardeman 1992).
Howe (1969)'s λ_3 formula is used.

Ratios can be lognormally distributed, in which case the geometric (or multiplicative)
mean and standard deviation can be reported as: GMean ×/ GSD (Limpert and Stahel 2011).

Cox (2018) discusses labelling logarithmically scaled axes in detail.
The command niceloglabels can be helpful here (Cox 2018, 2020).
I have made use of some of it inside blandaltman in an attempt to provide publication ready graphs.
Labelling that I consider "nice" may not be labelling that you consider "nice".
You might prefer to specify different value labels and ticks, by specifying e.g. xlabel() and xtick().

Examples

To run these examples you will have to change directory to where you installed the datasets associated with the command blandaltman
(assuming you installed the datasets as well as the command).

The 4 types of Bland-Altman plots that are readily created with blandaltman

This example also helps the user to decide whether heteroscedasticity is evident in a plot featuring differences or %differences (or ratios)

. `"use http://fmwww.bc.edu/repec/bocode/l/labmeasures.dta, clear"'

. blandaltman plexrbp4µmoll nimanurbp4µmoll, plot(difference percentmean percentlmean ratio)

After seeing the output from the above command, it could be assumed that
the distribution of percentage differences or ratios does not
vary with the magnitude of the measurements. If the user is happy to also assume normality
of percentage differences or log ratios, one of these plots might be preferred:

. blandaltman plexrbp4µmoll nimanurbp4µmoll, plot(percentmean percentlmean ratio) horizontal ciloa cibias

Numbers or equations can be added using text(). Note, the range of the x-axis has also been increased:

. `"blandaltman plexrbp4 nimanurbp4, plot(percentmean) h ciloa cibias xscale(range(6)) text(23 4.5 "23%" "(20% to 28)") text(-44 4.5 "-44%" "(-48% to -40%)") text(-10 4.5 "-10%" "(-12% to -8)")"'

Other intervals that can be displayed with blandaltman

This example gives a flavour of what other intervals are possible to display,
assuming the distribution of differences (or percentage differences or log ratios) is normal and does not vary with the magnitude of the measurements.
You won't want them all! See Remarks.
Bland and Altman's (1986) PEFR dataset is used.

. `"use http://fmwww.bc.edu/repec/bocode/p/PEFR.dta, clear"'

. `"blandaltman Wright Mini, plot(difference) h ciloa cibias predint ticonf(95) loaopts(lc(red)) ciloaopts(mc(red) lc(red)) legend(on order(2 "Bias (& 95% CI)" 4 "95% LoA (& 95% CI)" 6 "95% PI" 8 "95% TI with 95% conf."))"'

Note. legend(on) needed to be used as an option prior to knowing how to write the more complicated legend() specification above.

Stored results

With the exception of some of the regression output, blandaltman stores every element of its output in r():

. `"return list"'

References

Bland, J. M. and D. G. Altman. 1986. Statistical methods for assessing agreement between two methods of clinical measurement. Lancet 327: 307–10.

Bland, J. M. and D. G. Altman. 1999. Measuring agreement in method comparison studies. Statistical Methods in Medical Research 8: 135-160.

Carkeet, A. 2015. Exact parametric confidence intervals for Bland–Altman limits of agreement. Optometry and Vision Science 92: e71–e80.

Carkeet, A. and Y. T. Goh. 2018. Confidence and coverage for Bland–Altman limits of agreement and their approximate confidence intervals. Statistical Methods in Medical Research 27: 1559-1574.

Chatfield, M. 2021. Tolerance: Stata module to calculate tolerance intervals (normal distribution). Statistical Software Components S459009, Boston College Department of Economics.

Chatfield M. D., Cole T. J., de Vet H. C. W., Marquart-Wilson L. and D. M. Farewell. 2023. blandaltman: A command to create variants of Bland-Altman plots. Stata Journal 23: 851-874.

Cox, N. J. 2018. Speaking Stata: Logarithmic binning and labelling. Stata Journal 18: 262–286.

Cox, N. J. 2020. Software update for niceloglabels. Stata Journal 20: 1028-1030.

Francq, B. G., M. Berger and C. Boachie. 2020. To tolerate or to agree: A tutorial on tolerance intervals in method comparison studies with BivRegBLS R Package. Statistics in Medicine 39: 4334-4349.

Gerke, O. 2020. Reporting standards for a Bland-Altman agreement analysis: a review of methodological reviews. Diagnostics 10: 334.

Howe, W. G. 1969. Two-sided tolerance limits for normal populations - some improvements. Journal of the American Statistical Association 64: 610–620.

Limpert, E. and W. A. Stahel. 2011. Problems with using the normal distribution – and ways to improve quality and efficiency of data analysis. PLoS ONE 6: e21403.

Ludbrook, J. 2010. Confidence in Altman–Bland plots: a critical review of the method of differences. Clinical and Experimental Pharmacology and Physiology 37: 143–149.

Meeker, W. Q., G. J. Hahn and L. A. Escobar. 2017. Statistical Intervals: A guide for practitioners and researchers. Second edition. John Wiley & Sons, Inc.

Royston, P. and J. N. S Matthews. 1991. Estimation of reference ranges from normal samples. Statistics in Medicine 10: 691-695.

Shieh, G. 2018. The appropriateness of Bland-Altman's approximate confidence intervals for limits
of agreement. BMC Medical Research Methodology 18:45.

Vangel, M. G. 2005. Tolerance Interval. In The Encyclopedia of Biostatistics, 2nd Edition, edited by P. Armitage and T. Colton. John Wiley & Sons, Ltd.

Vardeman, S. B. 1992. What about the Other Intervals? The American Statistician 46: 193-197.

Vock, M. 2016. Intervals for the assessment of measurement agreement: Similarities, differences, and consequences of incorrect interpretations. Biometrical Journal 58, 489–501.

Author

Mark Chatfield, The University of Queensland, Australia.

m.chatfield@uq.edu.au

Acknowledgements

I have incorporated some of the syntax from the niceloglabels command (Cox 2018, 2020),
and the expanded and corrected version of the tolerance command (Chatfield 2021).

Over the years, I have used Adrian Mander's batplot command to visually assess heteroscedasticity in a plot of differences against means.
blandaltman extends this for plots featuring %differences or ratios.

Also see

Help: niceloglabels (if installed),
tolerance (if 2021 not 2006 version installed),
concord (if installed), kappaetc (if installed),
rmloa (if installed), biasplot (if installed),
pairplot (if installed), batplot (if installed),
baplot (if installed), agree (if installed)