Title: | Plots (Slightly Extended) Bland-Altman Plots |
---|---|
Description: | Bland-Altman Plots using either base graphics or ggplot2, augmented with confidence intervals, with detailed return values and a sunflowerplot option for data with ties. |
Authors: | Bernhard Lehnert |
Maintainer: | Bernhard Lehnert <[email protected]> |
License: | GPL |
Version: | 0.3.1 |
Built: | 2024-12-01 08:43:21 UTC |
Source: | CRAN |
Bland-Altman Plots for assessing agreement between two methods of clinical measurement and returning associated statistics. Plots are optionally extended by confidence intervals as described in "J. Martin Bland, Douglas G. Altman (1986): Statistical Methods For Assessing Agreement Between Two Methods Of Clinical Measurement" but not included in the graphics of that publication. Either base graphics or ggplot2 can be used.
Package: | BlandAltmanLeh |
Type: | Package |
Version: | 0.3.1 |
Date: | 2015-12-23 |
License: | GPL |
Bland Altman plots are a diagnostic tool for assessing the agreement between two methods of measurement or assessing retest reliability from two measurements. This package offers plots in base and ggplot2 graphics as well as detailed descriptive statistics, thus supporting the construction of individual plots based on Bland Altman plots. Bland and Altman describe a way for constructing confidence intervals. This package computes these confidence intervals and includes them into the plots. It also invents the Sunflower-Bland-Altman plot for data with ties.
Bernhard Lehnert
Maintainer: Bernhard K. Lehnert <[email protected]>
Bland JM, Altman DG, Statistical Methods For Assessing Agreement Between Two Methods Of Clinical Measurement, Lancet, 1986; 307-310.
Altman DG, Bland JM, Measurement in medicine: the analysis of method comparison studies, The Statistician 1983; 32, 307-317.
Vaz S et al., The Case for Using the Repeatability Coeffcient When Calculating Test-Retest Reliability, PLOS ONE, Sept. 2013, Vol 8, Issue 9.
bland.altman.plot,bland.altman.stats
# simple basic Bland Altman plot a <- rnorm(40,30,10) b <- 1.01*a + rnorm(40) bland.altman.plot(a,b, xlab="mean", ylab="difference") # to get all the data for further analysis bland.altman.plot(a,b, xlab="mean", ylab="difference", silent=FALSE) # to include confidence intervals into the plot bland.altman.plot(a,b, xlab="mean", ylab="difference", conf.int=.95) # to plot in ggplot2 bland.altman.plot(a,b, graph.sys="ggplot2") # to mark ties in a Sunflower-Bland-Altman plot a <- sample(1:5, 40, replace=TRUE) b <- rep(c(1,2,3,3,5,5,5,5),5) bland.altman.plot(a, b, sunflower=TRUE)
# simple basic Bland Altman plot a <- rnorm(40,30,10) b <- 1.01*a + rnorm(40) bland.altman.plot(a,b, xlab="mean", ylab="difference") # to get all the data for further analysis bland.altman.plot(a,b, xlab="mean", ylab="difference", silent=FALSE) # to include confidence intervals into the plot bland.altman.plot(a,b, xlab="mean", ylab="difference", conf.int=.95) # to plot in ggplot2 bland.altman.plot(a,b, graph.sys="ggplot2") # to mark ties in a Sunflower-Bland-Altman plot a <- sample(1:5, 40, replace=TRUE) b <- rep(c(1,2,3,3,5,5,5,5),5) bland.altman.plot(a, b, sunflower=TRUE)
Peak expiratory flow data from 17 members of Bland's family, taken with two different instruments, each twice. This data is for explanatory use only. Columns 1 and 2 were measured with the "Wright" peak flow meter, columns 3 and 4 with the "Mini Wright" peak flow meter. These are the data behind fig. 1, fig. 2 and fig. 6 of the original paper and these can be easily reconstructed
bland.altman.PEFR
bland.altman.PEFR
An object of class data.frame
with 17 rows and 4 columns.
# this is what fig. 1. would have looked like in R: x <- bland.altman.PEFR[["bigger.first"]] y <- bland.altman.PEFR[["smaller.first"]] plot(x,y, xlab="PEFR by large meter",ylab="PEFR by mini meter", xlim=c(0,800), ylim=c(0,800)) abline(0,1)
# this is what fig. 1. would have looked like in R: x <- bland.altman.PEFR[["bigger.first"]] y <- bland.altman.PEFR[["smaller.first"]] plot(x,y, xlab="PEFR by large meter",ylab="PEFR by mini meter", xlim=c(0,800), ylim=c(0,800)) abline(0,1)
Produce Bland-Altman Plot
Bland-AltmanPlots for assessing agreement between two measuring methods or repeatability (test-retest agreement) of measurements. Using either base graphics or ggplot2.
bland.altman.plot(group1, group2, two = 1.96, mode = 1, graph.sys = "base", conf.int = 0, silent = TRUE, sunflower = FALSE, geom_count = FALSE, ...)
bland.altman.plot(group1, group2, two = 1.96, mode = 1, graph.sys = "base", conf.int = 0, silent = TRUE, sunflower = FALSE, geom_count = FALSE, ...)
group1 |
Measurements with first method or first measurement |
group2 |
Measurements with second method or second measurement |
two |
Lines are drawn "two" standard deviations from mean differences. This defaults to 1.96 for proper 95 percent confidence interval estimation but can be set to 2.0 for better agreement with e. g. the Bland Altman publication. |
mode |
if 1 then difference group1 minus group2 is used, if 2 then group2 minus group1 is used. Defaults to 1. |
graph.sys |
Graphing system within R. This defaults to "base" but can be
one out of |
conf.int |
Defaults to 0 which draws the usual Bland Altman plot which contains no confidence intervalls. Change to .95 for 95 percent confidence intervalls to be drawn. |
silent |
logical. If graph.sys=="base" and silent==TRUE then no return value. If graph.sys=="base" and silent==FALSE then returns statistics. |
sunflower |
logical. If TRUE, the plot will be based on a sunflower plot
and ties will be marked accordingly. Try with data with ties. Works only with
|
geom_count |
logical. If TRUE, the dots will get larger the more frequent
given pair is. Use in presence of ties. Works only with
|
... |
passed on to graphics functions if |
Depends on graphic system chosen. In case of "base" depending on whether
silent==TRUE. If silent==TRUE then no returns. If silent==FALSE than returns
list of statistics as returned by bland.altman.stats()
. In case the
graphics system is "ggplot2" than the graphic object is returned so that it
can be printed or altered.
Bernhard Lehnert <[email protected]>
bland.altman.plot(rnorm(20), rnorm(20), xlab="mean measurement", ylab="differences", main="Example plot") bland.altman.plot(rnorm(20), 2+.8*rnorm(20), xlab="mean measurement", ylab="differences", conf.int=.95) bland.altman.plot(rnorm(200), 2+.8*rnorm(200), xlab="mean measurement", ylab="differences", conf.int=.95) # this is what fig.2 in Bland&Altman1986 would have looked like PEFR1 <- bland.altman.PEFR[,1] PEFR2 <- bland.altman.PEFR[,3] bland.altman.plot(PEFR1, PEFR2, silent=TRUE, xlim=c(0,800), xlab="Average PEFR by two meters", ylab="Difference in PEFR (large-mini)") # and this is the same but with additional 95 percent CIs data(bland.altman.PEFR) bland.altman.plot(PEFR1, PEFR2, silent=TRUE, conf.int=.95, xlim=c(0,800)) # an example with many ties and the 'sunflower'-option a <- rep(c(1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,5,6,6),2) b <- rep(c(1,1,1,2,2,2,3,1,4,2,5,3,3,3,3,3),3) bland.altman.plot(a,b,sunflower=TRUE, xlab="Mean",ylab="Difference", main="discrete values lead to ties") library(ggplot2) a <- bland.altman.plot(rnorm(20), rnorm(20), graph.sys="ggplot2", conf.int=.9) print(a + xlab("you can change this later") + ggtitle("Title goes here"))
bland.altman.plot(rnorm(20), rnorm(20), xlab="mean measurement", ylab="differences", main="Example plot") bland.altman.plot(rnorm(20), 2+.8*rnorm(20), xlab="mean measurement", ylab="differences", conf.int=.95) bland.altman.plot(rnorm(200), 2+.8*rnorm(200), xlab="mean measurement", ylab="differences", conf.int=.95) # this is what fig.2 in Bland&Altman1986 would have looked like PEFR1 <- bland.altman.PEFR[,1] PEFR2 <- bland.altman.PEFR[,3] bland.altman.plot(PEFR1, PEFR2, silent=TRUE, xlim=c(0,800), xlab="Average PEFR by two meters", ylab="Difference in PEFR (large-mini)") # and this is the same but with additional 95 percent CIs data(bland.altman.PEFR) bland.altman.plot(PEFR1, PEFR2, silent=TRUE, conf.int=.95, xlim=c(0,800)) # an example with many ties and the 'sunflower'-option a <- rep(c(1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,5,6,6),2) b <- rep(c(1,1,1,2,2,2,3,1,4,2,5,3,3,3,3,3),3) bland.altman.plot(a,b,sunflower=TRUE, xlab="Mean",ylab="Difference", main="discrete values lead to ties") library(ggplot2) a <- bland.altman.plot(rnorm(20), rnorm(20), graph.sys="ggplot2", conf.int=.9) print(a + xlab("you can change this later") + ggtitle("Title goes here"))
Does the computation for Bland Altman plots. This will usually be called from
graphic functions like bland.altman.plot
but will be usefull for
customized plot (see examples for color coded BA plot). Offers symmetric
confidence intervalls for bias and upper and lower limits.
bland.altman.stats(group1, group2, two = 1.96, mode = 1, conf.int = 0.95)
bland.altman.stats(group1, group2, two = 1.96, mode = 1, conf.int = 0.95)
group1 |
vector of numerics to be compared to group2 |
group2 |
vector of numerics to be compared to group1 |
two |
numeric defines how many standard deviations from mean are to be computed, defaults to 1.96 as this gives proper 95 percent CI. However, in the original publication a factor of 2 is used. |
mode |
if 1 then difference group1 minus group2 is used, if 2 then group2 minus group1 is used. Defaults to 1. |
conf.int |
usefull |
means
vector of means, i. e. data for the x axis
diffs
vector of differences, i. e. data for the y axis
groups
data.frame containing pairwise complete cases of group1 and
group2. NAs are removed.
based.on
count of pairwise complete cases in groups
lower.limit
lower limit for BA plot
mean.diffs
mean of differences, also called 'bias'
upper.limit
upper limit for BA plot
lines
vector containing y values where to draw horizontal
lines, i. e. mean of differences minus "two" standard deviations, mean of
differences and mean of differences plus "two" standard deviations (i. e.
c(lower.limit, mean.diffs, upper.limit
). This is convenient for
printing.
CI.lines
vector of confidence intervalls for the values of
lines (based on the assumption of normal distribution of differences
diffs
).
two
the argument 'two'
critical.diff
critical difference, i. e. 'two' times standard
deviation of differences, equals half the difference of lower.limit and
upper.limit
Bernhard Lehnert <[email protected]>
# simple calculation of stats: a <- rnorm(20) b <- jitter(a) print(bland.altman.stats(a, b)) print(bland.altman.stats(a, b)$critical.diff) # drawing Bland-Altman-Plot with color coding sex: example.data <- data.frame(sex = gl(2,6,labels=c("f","m")), m1 = c(16,10,14,18,16,15,18,19,14,11,11,17), m2 = c(18, 9,15,19,19,13,19,20,14,11,13,17)) ba <- bland.altman.stats(example.data$m1, example.data$m2) plot(ba$means, ba$diffs, col=example.data$sex, ylim=c(-4,4)) abline(h=ba$lines, lty=2) # compute 95%-CIs for the bias and upper and lower limits of PEFR data as # in Bland&Altman 1986 bland.altman.stats(bland.altman.PEFR[,1],bland.altman.PEFR[,3])$CI.lines # apparently wrong results? CAVE: Bland&Altman are using two=2, thus bland.altman.stats(bland.altman.PEFR[,1],bland.altman.PEFR[,3], two=2)$CI.lines
# simple calculation of stats: a <- rnorm(20) b <- jitter(a) print(bland.altman.stats(a, b)) print(bland.altman.stats(a, b)$critical.diff) # drawing Bland-Altman-Plot with color coding sex: example.data <- data.frame(sex = gl(2,6,labels=c("f","m")), m1 = c(16,10,14,18,16,15,18,19,14,11,11,17), m2 = c(18, 9,15,19,19,13,19,20,14,11,13,17)) ba <- bland.altman.stats(example.data$m1, example.data$m2) plot(ba$means, ba$diffs, col=example.data$sex, ylim=c(-4,4)) abline(h=ba$lines, lty=2) # compute 95%-CIs for the bias and upper and lower limits of PEFR data as # in Bland&Altman 1986 bland.altman.stats(bland.altman.PEFR[,1],bland.altman.PEFR[,3])$CI.lines # apparently wrong results? CAVE: Bland&Altman are using two=2, thus bland.altman.stats(bland.altman.PEFR[,1],bland.altman.PEFR[,3], two=2)$CI.lines