* Dataset and formulae from: * 1) http://www-users.york.ac.uk/~mb55/meas/ba.htm * 2) Bland JM, Altman DG. Measuring agreement in method comparison studies. * Statistical Methods in Medical Research 1999; 8: 135-160 * READ CAREFULLY BOTH PAPERS BEFORE USING THE MACRO *. ******************************************************* * B A L O A 2.0 * ******************************************************* * The MACRO needs that 'C:\Temp\' folder exists * * Runs with SPSS 14 or newer * ******************************************************* * (C) Marta García-Granero 03/2009 * * send questions to: mgarciagranero@gmail.com * *******************************************************. DEFINE BALOA(!POSITIONAL=!TOKENS(1)/!POSITIONAL=!TOKENS(1)/norm= !DEFAULT(H) !TOKENS(1)). DATASET NAME OriginalData. DATASET COPY WorkingData. DATASET DECLARE Results WINDOW=HIDDEN. DATASET ACTIVATE WorkingData. COUNT nmiss = !1 !2 (SYSMIS) . SELECT IF (nmiss=0). COMPUTE Mean=(!1+!2)/2. COMPUTE Diff=(!1-!2). !LET !vname=!CONCAT(!QUOTE(!1),',',!QUOTE(!2)). * Compute critical value for Student's t distribution *. RANK VARIABLES=!1(A) /N INTO N1@ /PRINT=NO . DO IF $casenum EQ 1. - COMPUTE TValue = IDF.T(0.975,N1@-1) . END IF. MATRIX. PRINT /TITLE='Bland & Altman LOA Analysis '. GET T95 /VAR=TValue /MISSING=OMIT. GET Mean /VAR= Mean. GET diff /VAR= Diff. COMPUTE n=NROW(Mean). COMPUTE minrange=CMIN(diff)-0.1*(CMAX(diff)-CMIN(diff)). COMPUTE maxrange=CMAX(diff)+0.1*(CMAX(diff)-CMIN(diff)). COMPUTE averdiff=MSUM(diff)/n. COMPUTE sddiff=SQRT((CSSQ(diff)-n*averdiff&**2)/(n-1)). COMPUTE gmean=MSUM(mean)/n. COMPUTE tvalue=averdiff/(sddiff/SQRT(n)). COMPUTE pvalue=2*(1-TCDF(ABS(tvalue),n-1)). COMPUTE lower=averdiff-1.96*sddiff. COMPUTE upper=averdiff+1.96*sddiff. COMPUTE minrange=CMIN(diff)-0.1*(CMAX(diff)-CMIN(diff)). DO IF lower LT minrange. - COMPUTE minrange=lower-0.1*(CMAX(diff)-CMIN(diff)). END IF. COMPUTE maxrange=CMAX(diff)+0.1*(CMAX(diff)-CMIN(diff)). DO IF upper GT maxrange. - COMPUTE maxrange=upper+0.1*(CMAX(diff)-CMIN(diff)). END IF. COMPUTE cr=100*sddiff/gmean. * Confidence interval for bias *. COMPUTE low95=averdiff-T95*sddiff/SQRT(n). COMPUTE upp95=averdiff+T95*sddiff/SQRT(n). * Confidence interval for agreement limits *. COMPUTE SELOA=SQRT(((1/n)+(1.96**2)/(2*(n-1)))*sddiff**2). COMPUTE low95low=lower-T95*SELOA. COMPUTE upp95low=lower+T95*SELOA. COMPUTE low95upp=upper-T95*SELOA. COMPUTE upp95upp=upper+T95*SELOA. COMPUTE vname={!vname}. * REPORTS *. PRINT {averdiff,sddiff,gmean} /FORMAT='F8.3' /CLABELS='MeanDiff','SD(Diff)','G-Mean' /TITLE='Statistics (*)'. PRINT vname /FORMAT='A8' /CLABELS='Method 1','Method 2' /TITLE='(*) Methods compared:'. PRINT {averdiff,SDDiff/SQRT(n),low95,upp95,tvalue,pvalue} /FORMAT='F8.3' /CLABEL='MeanDiff','Se(Diff)','Low95%CL','Upp5%CL','t-value','2-tail p' /TITLE='Paired samples t-test for the significance of bias'. PRINT{lower,low95low,upp95low;upper,low95upp,upp95upp} /FORMAT='F8.3' /RLABELS='Lower','Upper' /CLABELS='LOA','Low95%CL','Upp95%CL' /TITLE='Limits of agreement (with 95%CI)'. PRINT cr /FORMAT='F8.1' /RLABEL='RSDR(%)=' /TITLE='Reproducibility relative standard deviation'. SAVE {averdiff,lower,upper,minrange,maxrange} /OUTFILE=Results. END MATRIX. * Add data to file *. DATASET ACTIVATE Results. PRESERVE. SET LOCALE=ENGLISH. STRING #var1 TO #var5 (A12). DO REPEAT A=#var1 TO #var5 /B=col1 TO col5. - COMPUTE A = STRING(B,E11.3). END REPEAT. !LET !reflin1=!UNQUOTE(#var1). !LET !reflin2=!UNQUOTE(#var2). !LET !reflin3=!UNQUOTE(#var3). !LET !ymin= !UNQUOTE(#var4). !LET !ymax= !UNQUOTE(#var5). * Write Graph to syntax file *. WRITE OUTFILE 'c:\temp\LOAGraph.sps' /"IGRAPH" /" /VIEWNAME='Bland-Altman LOA plot'" /" /X1 = VAR(Mean) TYPE = SCALE" /" /Y = VAR(Diff) TYPE = SCALE (MIN="!ymin" MAX="!ymax")" /" /COORDINATE = VERTICAL" /" /X1LENGTH=4.0" /" /YLENGTH= 3.0" /" /REFLINE Diff "!reflin1 /" /REFLINE Diff "!reflin2 /" /REFLINE Diff "!reflin3 /" /TITLE=' Bland-Altman plot (with LOA)'" /" /CAPTION=' Methods compared: " !QUOTE(!1) " & " !QUOTE(!2) "'" /" /SCATTER COINCIDENT = NONE.". CACHE. /* Necessary to avoid an error *. EXE. /* including the syntax file later *. DATASET ACTIVATE WorkingData. DATASET CLOSE Results. INCLUDE 'C:\Temp\LOAGraph.sps'. RESTORE. * Normality of diferences *. !IF ( !UPCASE(!norm)='H' ) !THEN FREQUENCIES VARIABLES=Diff /FORMAT=NOTABLE /STATISTICS=SKEWNESS SESKEW KURTOSIS SEKURT /HISTOGRAM NORMAL. !ELSE EXAMINE VARIABLES=Diff /PLOT BOXPLOT NPPLOT. !IFEND. * Correlation between ABS(Diff)&Mean (looking for error proportional to the mean) *. COMPUTE Diff=ABS(Diff). VAR LABEL Diff'Abs. differences'. NONPAR CORR /VARIABLES=Mean Diff /PRINT=SPEARMAN TWOTAIL NOSIG. * Get rid of copy of dataset *. DATASET ACTIVATE OriginalData. DATASET CLOSE WorkingData. !ENDDEFINE. * Sample dataset (from 1st paper) *. DATA LIST LIST/subject wright1 wright2 mini1 mini2 (5 F8). BEGIN DATA 1 494 490 512 525 2 395 397 430 415 3 516 512 520 508 4 434 401 428 444 5 476 470 500 500 6 557 611 600 625 7 413 415 364 460 8 442 431 380 390 9 650 638 658 642 10 433 429 445 432 11 417 420 432 420 12 656 633 626 605 13 267 275 260 227 14 478 492 477 467 15 178 165 259 268 16 423 372 350 370 17 427 421 451 443 END DATA. VAR LEVEL ALL(SCALE). * Macro call: 2 arguments are mandatory (the 2 methods to be compared) and one (norm, with 2 possible values, H and SW) is optional: if sample size is small, use SW to check for normality (Shapiro-Wilk&boxplot) otherwise use H (histogram with normal curve plotted) . BALOA wright1 mini1 norm=SW.