You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

219 lines
6.5 KiB
Plaintext

*! baplot.ado version 1.21 written by PTS (p.seed@umds.ac.uk) (STB-55: sbe33)
*! Produces Bland-Altman plots for two variables
*! See Bland & Altman Lancet Feb 8 1986, pp 307-310
*!
*! syntax: baplot var1 var2 if in, symbol(symbol) format(%6.3f) avlab("Average") difflab("Difference") yline(str) textsize(#) other graph options
* Now allows choice of symbol, and extra ylines Feb 8 1996
* larger plotting symbols for overlapping points
* Silly comparisons taken out
cap prog drop baplot
prog define baplot
version 6.0
* set trace off
syntax varlist(min=2 max=2 numeric) [if] [in], /*
*/ [Symbol(string) format(string) avlab(string) difflab(string) /*
*/ novars noGRaph ci zero mean yline(string) diag saving(string) /*
*/ text(real 100) ratio(real 1) *]"
parse "`varlist'", parse(" ")
local m1 "`1'"
local m2 "`2'"
if "`symbol'" == "" { local symbol "o" }
if "`format'" == "" {local format "%6.3f" }
if "`saving'" ~= "" { local saving "saving(`saving')"}
if "`ci'" ~= "" {local mean = "mean" }
preserve
tempvar touse
mark `touse' `if' `in'
markout `touse' `m1' `m2'
qui keep if `touse'
tempvar av diff
if "`avlab'" == "" { local avlab "Average"}
if lower("`avlab'") == "nolab" { local avlab " "}
if "`difflab'" == "" { local difflab "Difference" }
if lower("`difflab'") == "nolab" { local difflab " "}
qui gen `av' = (`m1' + `m2')/2
qui gen `diff' = `m1' - `m2'
label var `av' "`avlab'"
label var `diff' "`difflab'"
qui summ `diff' if `touse'
local xbar = _result(3)
local sd = _result(4)^.5
local n = _result(2)
local se = `sd'/`n'^.5
local t = invt(_result(2)-1, .95)
local lrr = `xbar' - 2*`sd'
local urr = `xbar' + 2*`sd'
local min = _result(5)
local max = _result(6)
local lcb = `xbar' - `t'*`se'
local ucb = `xbar' + `t'*`se'
summ `av', meanonly
local xmin = _result(5)
local xmax = _result(6)
local yline "`lrr', `urr'"
if "`ci'" ~= "" {
local yline "`yline', `lcb', `ucb'"
}
if "`mean'" ~= "" | "`zero'" == "" {local yline "`yline', `xbar'"}
if "`zero'" ~= "" {local yline "`yline', 0"}
qui corr `av' `diff'
local r = _result(4)
local n = _result(1)
local sig = tprob(`n'-2, `r'*((`n'-2)/(1-`r'^2))^.5)
#delim ;
di in gr _n "Bland-Altman comparison of `m1' and `m2'";
di in gr "Limits of agreement (Reference Range for difference): " in ye `format' `lrr'
in gr " to " in ye `format' `urr' ;
di in gr "Mean difference: " in ye `format' `xbar'
in gr " (CI " in ye `format' `lcb'
in gr " to " in ye `format' `ucb'
in gr ") ";
di in gr "Range : " in ye `format' `xmin'
in gr " to " in ye `format' `xmax';
di in gr "Pitman's Test of difference in variance: r = " in ye `format' `r'
in gr ", n = " in ye `n'
in gr ", p =" in ye `format' `sig' ;
#delim cr
if "`vars'" ~= "" {
qui corr `m1' `m2', cov
local tau = _result(4)
qui summ `m1'
local err1 = _result(4) - `tau'
qui summ `m2'
local err2 = _result(4) - `tau'
di in gr "Estimated variance of true measure: " in ye `format' `tau'
di in gr "Estimated error variance (`1'): " in ye `format' `err1'
di in gr "Estimated error variance (`2'): " in ye `format' `err2'
di in gr "Very low or negative error variances may indiate that modelling assumptions are violated."
}
global S_1 `xbar'
global S_2 `lrr'
global S_3 `urr'
if "`graph'" == "" & "`diag'" == "" {
sort `diff' `av'
tempvar f n
qui by `diff' `av': gen `f' = _N if `diff' ~= . & `av' ~= .
qui by `diff' `av': gen `n' = _n if `diff' ~= . & `av' ~= .
graph `diff' `av' if `touse' & `n' == 1 [fw=`f'], symbol(`symbol') `xlabel' `ylabel' yline(`yline') `saving' `options'
}
else if "`diag'" ~= "" {
local nobs = _N + 1
qui set obs `nobs'
qui replace `m2' = 0 if `m2' == .
* loa
tempvar lb ub
qui gen `ub' = `m2' + `xbar' + 2*`sd'
qui replace `ub' = . if `ub' < 0
summ `ub', mean
qui replace `ub' = . if `ub' > _result(5) & `ub' < _result(6)
qui gen `lb' = `m2' + `xbar' - 2*`sd'
summ `lb', mean
if _result(5) < 0 {
qui replace `lb' = . if `lb' < 0
local nobs = _N + 1
qui set obs `nobs'
qui replace `lb' = 0 if _n == _N
qui replace `m2' = 2*`sd' - `xbar' if _n == _N
}
summ `lb', mean
qui replace `lb' = . if `lb' > _result(5) & `lb' < _result(6)
* ci
if "`ci'" ~= "" {
tempvar lci uci
qui gen `lci' = `m2' + `xbar' - invt(`n'-1,0.95)*`sd'/`n'^.5
qui gen `uci' = `m2' + `xbar' + invt(`n'-1,0.95)*`sd'/`n'^.5
summ `lci', mean
if _result(5) < 0 {
qui replace `lci' = . if `lci' < 0
local nobs = _N + 1
qui set obs `nobs'
qui replace `lci' = 0 if _n == _N
qui replace `m2' = invt(`n'-1,0.95)*`sd'/`n'^.5 - `xbar' if _n == _N
}
summ `uci', mean
if _result(5) < 0 {
qui replace `uci' = . if `uci' < 0
local nobs = _N + 1
qui set obs `nobs'
qui replace `uci' = 0 if _n == _N
qui replace `m2' = - invt(`n'-1,0.95)*`sd'/`n'^.5 - `xbar' if _n == _N
}
summ `lci', mean
qui replace `lci' = . if `lci' > _result(5) & `lci' < _result(6)
summ `uci', mean
qui replace `uci' = . if `uci' > _result(5) & `lci' < _result(6)
}
summ `m2' if `m2' ~= ., mean
tempvar diag
* zero
if "`zero'" ~= "" | "`mean'" == "" {
qui gen `diag' = `m2' if `m2' == _result(5) | `m2' == _result(6)
}
* mean
else {
qui gen `diag' = `m2' + `xbar' if `m2' == _result(5) | `m2' == _result(6)
summ `diag', mean
if _result(5) < 0 {
qui replace `diag' = . if `diag' < 0
local nobs = _N + 1
qui set obs `nobs'
qui replace `diag' = 0 if _n == _N
qui replace `m2' = - `xbar' if _n == _N
}
}
sort `m1' `m2'
tempvar f n
qui by `m1' `m2': gen `f' = _N
qui by `m1' `m2': gen `n' = _n
if ("`xlabel'" == "" | "`ylabel'" == "") & index("`options'","xlab") == 0 & index("`options'","ylab") == 0 {
nicenum labels = 0 `m1' `m2'
local xlabel xlab($labels)
local ylabel ylab($labels)
}
local r_tx = int(923 * `text'/100)
local c_tx = int(444 * `text'/100)
local c_min = int(16000 - (23063*`ratio'/2))
local c_max = int(16000 + (23063*`ratio'/2))
di "bbox(0,`c_min',23063,`c_max',`r_tx',`c_tx',0) "
gph open, `saving'
graph `m1' `diag' `ub' `lb' `lci' `uci' `m2' if `n' == 1 [fw=`f'], /*
*/ `xlabel' `ylabel' s(oiiiii) c(.lllll) sort /*
*/ bbox(0,`c_min',23063,`c_max',`r_tx',`c_tx',0) `options'
gph close
}
end
exit