********************************************* * 95% & 99% CI FOR MEDIAN DIFFERENCES * * (UNPAIRED AND PAIRED SAMPLES) * ********************************************* * (c) Marta Garcia-Granero (07/2008) * * mgarciagranero@gmail.com * * Downloaded from: http://gjyp.nl/marta/ * * Feel free to use or modify this code, but * * acknowledge the author and the web site * ********************************************* * Campbell MJ, Gardner MJ "Medians and their differences" * in Altman, Douglas A.(Editor). Statistics with Confidence. * London,GBR: BMJ Publishing Group, 2000. Chapter 5. DEFINE ICMANNWHITNEY (!POS !TOKENS(1)/!POS !TOKENS(1)). DATASET NAME Data. DATASET DECLARE Results WINDOW=HIDDEN. PRESERVE. SET ERRORS=NONE RESULTS=NONE. SET MXLOOPS=10000. MATRIX. GET nsdata /VAR = !2 !1 /NAMES = vname /MISSING = OMIT. COMPUTE data = nsdata. COMPUTE data(GRADE(nsdata(:,1)),:) = nsdata. RELEASE nsdata. COMPUTE totaln=NROW(data). COMPUTE ngrp1=data(1,1). COMPUTE ngrp2=data(totaln,1). COMPUTE groupvar=vname(1). COMPUTE n=CSUM(DESIGN(data(:,1))). COMPUTE group1=data(1:n(1),2). COMPUTE group2=data((n(1)+1):totaln,2). COMPUTE n1n2=n(1)&*n(2). COMPUTE diff=MAKE(1,n1n2,0). COMPUTE counter=1. LOOP i=1 TO n(1). - LOOP j=1 TO n(2). - COMPUTE diff(counter)=group1(i)-group2(j). - COMPUTE counter=counter+1. - END LOOP. END LOOP. COMPUTE sdiff = diff. COMPUTE sdiff(grade(diff)) = diff. RELEASE data,diff,group1,group2. COMPUTE pair=(TRUNC(n1n2/2) EQ n1n2/2). DO IF pair EQ 0. - COMPUTE median=sdiff((n1n2+1)/2). ELSE. - COMPUTE median=(sdiff(n1n2/2)+sdiff(1+(n1n2/2)))/2. END IF. RELEASE pair. COMPUTE depvarn=vname(2). DO IF ((n(1) LE 25) AND (n(2) LE 25)). * Table 18.5 from altman book *. - COMPUTE d95={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; 0,0,0,0,3,4,6,7,8,9,10,12,13,14,15,16,18,19,20,21,23,24,25,26,28; 0,0,0,0,4,6,7,9,11,12,14,15,17,18,20,22,23,25,26,28,30,31,33,34,36; 0,0,0,0,6,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45; 0,0,0,0,7,9,11,14,16,18,20,23,25,27,30,32,35,37,39,42,44,46,49,51,54; 0,0,0,0,8,11,13,16,18,21,24,27,29,32,35,38,40,43,46,49,51,54,57,60,63; 0,0,0,0,9,12,15,18,21,24,27,30,34,37,40,43,46,49,53,56,59,62,65,68,72; 0,0,0,0,10,14,17,20,24,27,31,34,38,41,45,48,52,56,59,63,66,70,74,77,81; 0,0,0,0,12,15,19,23,27,30,34,38,42,46,50,54,58,62,66,70,74,78,82,86,90; 0,0,0,0,13,17,21,25,29,34,38,42,46,51,55,60,64,68,73,77,81,86,90,95,99; 0,0,0,0,14,18,23,27,32,37,41,46,51,56,60,65,70,75,79,84,89,94,99,103,108; 0,0,0,0,15,20,25,30,35,40,45,50,55,60,65,71,76,81,86,91,97,102,107,112,118; 0,0,0,0,16,22,27,32,38,43,48,54,60,65,71,76,82,87,93,99,104,110,116,121,127; 0,0,0,0,18,23,29,35,40,46,52,58,64,70,76,82,88,98,100,106,112,118,124,130,136; 0,0,0,0,19,25,31,37,43,49,56,62,68,75,81,87,98,100,107,113,120,126,133,139,146; 0,0,0,0,20,26,33,39,46,53,59,66,73,79,86,93,100,107,114,120,127,134,141,148,155; 0,0,0,0,21,28,35,42,49,56,63,70,77,84,91,99,106,113,120,128,135,142,150,157,164; 0,0,0,0,23,30,37,44,51,59,66,74,81,89,97,104,112,120,127,135,143,151,158,166,174; 0,0,0,0,24,31,39,46,54,62,70,78,86,94,102,110,118,126,134,142,151,159,167,175,183; 0,0,0,0,25,33,41,49,57,65,74,82,90,99,107,116,124,133,141,150,158,167,176,184,193; 0,0,0,0,26,34,43,51,60,68,77,86,95,103,112,121,130,139,148,157,166,175,184,193,202; 0,0,0,0,28,36,45,54,63,72,81,90,99,108,118,127,136,146,155,164,174,183,193,202,212}. - COMPUTE d99={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; 0,0,0,0,1,2,2,3,4,5,6,7,8,8,9,10,11,12,13,14,15,15,16,17,18; 0,0,0,0,2,3,4,5,6,7,8,10,11,12,13,14,16,17,18,19,20,22,23,24,25; 0,0,0,0,2,4,5,7,8,10,11,13,14,16,17,19,20,22,23,25,26,28,30,31,33; 0,0,0,0,3,5,7,8,10,12,14,16,18,19,21,23,25,27,29,31,33,35,36,38,40; 0,0,0,0,4,6,8,10,12,14,17,19,21,23,25,28,30,32,34,37,39,41,44,46,48; 0,0,0,0,5,7,10,12,14,17,19,22,25,27,30,32,35,38,40,43,45,48,51,53,56; 0,0,0,0,6,8,11,14,17,19,22,25,28,31,34,37,40,43,46,49,52,55,58,61,64; 0,0,0,0,7,10,13,16,19,22,25,28,32,35,38,42,45,48,52,55,59,62,65,69,72; 0,0,0,0,8,11,14,18,21,25,28,32,35,39,43,46,50,54,58,61,65,69,73,76,80; 0,0,0,0,8,12,16,19,23,27,31,35,39,43,47,51,55,59,64,68,72,76,80,84,88; 0,0,0,0,9,13,17,21,25,30,34,38,43,47,52,56,61,65,70,74,79,83,88,92,97; 0,0,0,0,10,14,19,23,28,32,37,42,46,51,56,61,66,71,75,80,85,90,95,100,105; 0,0,0,0,11,16,20,25,30,35,40,45,50,55,61,66,71,76,82,87,92,97,103,108,113; 0,0,0,0,12,17,22,27,32,38,43,48,54,59,65,71,76,82,88,93,99,105,110,116,122; 0,0,0,0,13,18,23,29,34,40,46,52,58,64,70,75,82,88,94,100,106,112,118,124,130; 0,0,0,0,14,19,25,31,37,43,49,55,61,68,74,80,87,93,100,106,113,119,126,132,139; 0,0,0,0,15,20,26,33,39,45,52,59,65,72,79,85,92,99,106,113,119,126,133,140,147; 0,0,0,0,15,22,28,35,41,48,55,62,69,76,83,90,97,105,112,119,126,134,141,148,156; 0,0,0,0,16,23,30,36,44,51,58,65,73,80,88,95,103,110,118,126,133,141,149,156,164; 0,0,0,0,17,24,31,38,46,53,61,69,76,84,92,100,108,116,124,132,140,148,156,165,173; 0,0,0,0,18,25,33,40,48,56,64,72,80,88,97,105,113,122,130,139,147,156,164,173,181}. - COMPUTE u95=d95(n(1),n(2)). - COMPUTE u99=d99(n(1),n(2)). - DO IF u95 EQ 0. - COMPUTE u95=1. - COMPUTE u99=1. - END IF. - RELEASE d95,d99. ELSE. - COMPUTE u95=1+TRUNC(n1n2/2-1.959964*sqrt(n1n2*(n(1)+n(2)+1)/12)). - COMPUTE u99=1+TRUNC(n1n2/2-2.575829*sqrt(n1n2*(n(1)+n(2)+1)/12)). END IF. COMPUTE low95=sdiff(u95). COMPUTE high95=sdiff(n1n2+1-u95). COMPUTE low99=sdiff(u99). COMPUTE high99=sdiff(n1n2+1-u99). COMPUTE vnames={'Mediana','Inferio1','Superio1','Inferio2','Superio2'}. SAVE {Median,low95,high95,low99,high99} /OUTFILE=Results /NAMES=vnames. END MATRIX. RESTORE. DATASET ACTIVATE Results. VAR LABEL Mediana 'Median. Diff.'/Inferio1 'Lower 95%'/Superio1 'Upper 95%' /Inferio2 'Lower 99%'/Superio2 'Upper 99%'. OMS /SELECT TABLES /IF COMMANDS='Summarize' SUBTYPES='Case Processing Summary' /DESTINATION VIEWER=NO. SUMMARIZE /TABLES=ALL /FORMAT=LIST NOCASENUM NOTOTAL /TITLE='95% & 99% CI for median differences in unpaired samples (*)' /CELLS=NONE. OMSEND. DATASET ACTIVATE Data. DATASET CLOSE Results. ECHO '(*) Samples should be similar in shape&spread'. !ENDDEFINE. DEFINE ICWILCOXON(!POSITIONAL !TOKENS(2)). DATASET NAME Data. DATASET DECLARE Results WINDOW=HIDDEN. PRESERVE. SET ERRORS=NONE RESULTS=NONE. SET MXLOOPS=10000. MATRIX. GET data /VAR = !1 /NAMES = vname /MISSING = OMIT. COMPUTE n=NROW(data). COMPUTE d=data(:,1)-data(:,2). RELEASE data. COMPUTE nt=n*(n+1)/2. COMPUTE dmean=MAKE(1,nt,0). COMPUTE counter=1. LOOP i=1 TO n. - LOOP j=i TO n. - COMPUTE dmean(counter)=(d(i)+d(j))/2. - COMPUTE counter=counter+1. - END LOOP. END LOOP. COMPUTE sdmean=dmean. COMPUTE sdmean(GRADE(dmean)) = dmean. RELEASE counter,dmean. COMPUTE pair=(TRUNC(nt/2) EQ nt/2). DO IF pair EQ 0. - COMPUTE median=sdmean((nt+1)/2). ELSE. - COMPUTE median=(sdmean(nt/2)+sdmean(1+nt/2))/2. END IF. DO IF n LE 50. - COMPUTE w95={0,0,0,0,0,1,3,4,6,9,11,14,18,22,26,30,35,41,47,53,59,66,74,82,90, 99,108,117,127,138,148,160,171,183,196,209,222,236,250,265,280,295, 311,328,344,362,379,397,416,735}. - COMPUTE w99={0,0,0,0,0,0,0,0,1,2,4,6,8,10,13,16,20,24,28,33,38,43,49,55,62,69, 76,84,92,101,110,119,129,139,149,160,172,183,195,208,221,234,248, 262,277,292,308,323,340,356,374}. - COMPUTE u95=w95(n). - COMPUTE u99=w99(n). - RELEASE w95,w99. ELSE. - COMPUTE u95=1+TRUNC(nt/2-1.959964*sqrt(n*(n+1)*+(2*n+1)/24)). - COMPUTE u99=1+TRUNC(nt/2-2.575829*sqrt(n*(n+1)*+(2*n+1)/24)). END IF. COMPUTE low95=sdmean(u95). COMPUTE high95=sdmean(nt+1-u95). COMPUTE low99=sdmean(u99). COMPUTE high99=sdmean(nt+1-u99). COMPUTE vnames={'Mediana','Inferio1','Superio1','Inferio2','Superio2'}. SAVE {Median,low95,high95,low99,high99} /OUTFILE=Results /NAMES=vnames. END MATRIX. RESTORE. DATASET ACTIVATE Results. VAR LABEL Mediana 'Median. Diff.'/Inferio1 'Lower 95%'/Superio1 'Upper 95%' /Inferio2 'Lower 99%'/Superio2 'Upper 99%'. OMS /SELECT TABLES /IF COMMANDS='Summarize' SUBTYPES='Case Processing Summary' /DESTINATION VIEWER=NO. SUMMARIZE /TABLES=ALL /FORMAT=LIST NOCASENUM NOTOTAL /TITLE='95% & 99% CI for median differences in paired samples (*)' /CELLS=NONE. OMSEND. DATASET ACTIVATE Data. DATASET CLOSE Results. ECHO '(*) Differences must be symmetrical'. !ENDDEFINE. * Sample dataset #1 (unpaired samples), Table 5.1 in Altman book *. DATA LIST FREE/Group Globulin (2 F8). BEGIN DATA 1 38 1 26 1 29 1 41 1 36 1 31 1 32 1 30 1 35 1 33 2 45 2 28 2 27 2 38 2 40 2 42 2 39 2 39 2 34 2 45 END DATA. VALUE LABEL Group 1 'Group 1' 2 'Group 2'. * MACRO call (dependent variable goes first) *. ICMANNWHITNEY Globulin Group. * Sample dataset #2 (paired samples), Table 5.3 in Altman book *. DATA LIST FREE/Before After (2 F8.1). BEGIN DATA 10.6 14.6 5.2 15.6 8.4 20.2 9.0 20.9 6.6 24.0 4.6 25.0 14.1 35.2 5.2 30.2 4.4 30.0 17.4 46.2 7.2 37.0 END DATA. * MACRO call *. ICWILCOXON After Before.