*! version 1.0.0 22sep1997 program define symmetry version 5.0 local varlist "req ex min(2) max(2)" local if "optional" local options "NOTable CONtrib EXact" parse "`*'" qui { parse "`varlist'", parse(" ") /* ROUTINE FOR DISPLAYING CROSS TABULATION" */ tempvar touse mark `touse' `if' `in' markout `touse' `varlist', strok preserve stack `1' `touse' `2' `touse', into(`2' `touse') clear keep `2' `touse' sort `2' qui by `2': keep if `touse' qui by `2': keep if _n==1 tempfile tt save "`tt'" rename `2' `1' mcross using "`tt'" sort `1' `2' save "`tt'",replace restore,pres keep if `touse' tempvar cnt gen byte `cnt'=1 sort `1' `2' merge `1' `2' using "`tt'" drop _merge keep if `touse' sort `1' `2' replace `cnt'=0 if `cnt'==. if "`notable'"~="notable" { noi table `1' `2',c(sum `cnt') row col center f(%5.0f) } tempvar scnt egen `scnt'=sum(`cnt'),by(`1' `2') sort `1' `2' by `1' `2':keep if _n==1 /*END OF CROSS TABULATION ROUTINE*/ /* SET UP TABLE*/ tempvar gro gco egen int `gro'=group(`1') egen int `gco'=group(`2') sum `gro',d local r=_result(6) sum `gco',d local c=_result(6) local i=1 while `i'<=`r' { local j=1 while `j'<=`r' { gen n`i'_`j'=0 replace n`i'_`j'=`scnt' if `gro'==`i' & `gco'==`j' local j=`j'+1 } local i=`i'+1 } collapse (sum) n1_1-n`r'_`r' /* END SET UP TABLE */ /* ROUTINE FOR MARGINAL HOMOGENEITY*/ local i=1 while `i'<=`r' { local j=1 gen r`i'=0 while `j'<=`r' { replace r`i'=r`i'+n`i'_`j' local j=`j'+1 } local i=`i'+1 } local i=1 while `i'<=`r' { local j=1 gen c`i'=0 while `j'<=`r' { replace c`i'=c`i'+n`j'_`i' local j=`j'+1 } local i=`i'+1 } local i=1 local d2=0 while `i'<=`r' { gen m`i' =0 replace m`i'=((r`i'-c`i')^2)/(r`i'+c`i') replace m`i'=0 if m`i'==. if r`i'==0 & c`i'==0 {local d2=`d2'+1} local i=`i'+1 } /* ROUTINE FOR MARGINAL HOMOGENEITY*/ local i=1 while `i'<=`r' { local j=1 gen mr`i'=0 while `j'<=`r' { replace mr`i'=mr`i'+n`i'_`j' if `i'~=`j' local j=`j'+1 } local i=`i'+1 } local i=1 while `i'<=`r' { local j=1 gen mc`i'=0 while `j'<=`r' { replace mc`i'=mc`i'+n`j'_`i' if `i'~=`j' local j=`j'+1 } local i=`i'+1 } local i=1 local md2=0 while `i'<=`r' { gen mm`i' =0 replace mm`i'=((mr`i'-mc`i')^2)/(mr`i'+mc`i') replace mm`i'=0 if mm`i'==. if mr`i'==0 & mc`i'==0 {local md2=`md2'+1} local i=`i'+1 } /* ROUTINE FOR SYMMETRY TEST */ if "`contrib'"=="contrib" { noi di noi di in green " Contribution" noi di in green " to Symmetry" noi di in green " Cells Chi-Square" noi di in green "______________ ______________" } local i=1 while `i'<=`r' { local j=1 while `j'<=`r' { gen x`i'_`j'=0 replace x`i'_`j'=((n`i'_`j'-n`j'_`i')^2)/ /* */ (n`i'_`j'+n`j'_`i') if `i'<`j' replace x`i'_`j'=0 if x`i'_`j'==. if `i'<`j' & "`contrib'"=="contrib" { noi di "n`i'_`j'" " & " /* */ "n`j'_`i'" " " %9.4f x`i'_`j' } local j=`j'+1 } local i=`i'+1 } /* END SYMMETRY TEST */ local totpair=0 local i=1 while `i'<=`r' { local j=1 while `j'<=`r' { local totpair=`totpair'+n`i'_`j' local j=`j'+1 } local i=`i'+1 } /*df CALCULATION */ local i=1 local d=0 while `i'<=`r' { local j=1 while `j'<=`r' { if n`i'_`j'==0 & n`j'_`i'==0 & `i'<`j' { local d=`d'+1 } local j=`j'+1 } local i=`i'+1 } local i=1 local x2=0 while `i'<=`r' { local j=1 while `j'<=`r' { local x2=`x2'+x`i'_`j' local j=`j'+1 } local i=`i'+1 } local i=1 local m=0 while `i'<=`r' { local m=`m'+m`i' local i=`i'+1 } local i=1 local mm=0 while `i'<=`r' { local mm=`mm'+mm`i' local i=`i'+1 } local df=(`r'*(`r'-1)/2)-`d' local df2=(`r'-1)-`d2' local k=`r'-`md2' local df3=`k'-1 local p=chiprob(`df',`x2') local p2=chiprob(`df2',`m') local p3=chiprob(`df3',(`k'-1)*`mm'/`k') gen pval=. if "`exact'"=="exact" { /* EXACT TEST LOGARITHM nxn tables */ keep n1_1-n`r'_`r' xpose,clear v rename _varname cell gen c1=real(substr(cell,2,index(cell,"_")-2)) gen c2=real(substr(cell,index(cell,"_")+1,.)) drop if c1==c2 tempfile one save `one' keep if c1>c2 tempfile two sort c1 c2 save `two' use `one',clear keep if c2>c1 rename c2 c3 rename c1 c2 rename c3 c1 rename v1 v2 sort c1 c2 merge c1 c2 using `two' assert _merge==3 drop c1 c2 _merge order cell v1 v2 gen den= v1+v2 gen N=den gen double oval=comb(N,v1)*(0.5)^N /* OBSERVED TABLE'S */ gen double obval=oval /* p-VALUE */ replace obval=oval*obval[_n-1] if _n>1 local obsval=obval[_N] gen den_n=den gen nv1=N gen nv2=0 gen u=N/2 if mod(N,2)==0 replace u=(N-1)/2 if mod(N,2)~=0 gen negu=-1*u sort negu local i 1 while `i'<=_N { local den`i'=den[`i'] local u`i'=u[`i'] /* upper bound for each variable */ local i=`i'+1 } local r=_N /* variables go from 1 to r=# of collumns */ clear /* First Observation */ set obs 1 /* set to zero vector */ local i=1 while `i'<=`r'{ gen v`i'=0 local i=`i'+1 } expand `u1'+1 replace v1=_n-1 local i=2 local myval "v1" gen double nnp=1 while `i'<=`r' { expand `u`i''+1 local myval "`myval' v`i'" parse "`myval'", parse(" ") sort `myval' by `myval': replace v`i'=_n-1 replace nnp=1 local j 1 while `j'<=`r' { replace nnp=nnp*comb(`den`j'',v`j')* /* */ (0.5)^`den`j'' local j=`j'+1 } drop if nnp>`obsval' local i=`i'+1 } sum v1-v`r' local i 1 gen double np=1 gen eq=0 while `i'<=`r' { replace np=np*comb(`den`i'',v`i')*(0.5)^`den`i'' replace eq=eq+1 if `den`i''-v`i'==v`i' local i=`i'+1 } keep if np<=`obsval' replace np=np*2^(`r'-eq) sort np egen double pval=sum(np) } /*end of exact for nxn */ noi di noi di in green /* */ " Chi-Squared df Prob>chi2" noi di in gr _dup(26) "-" "+" _dup(33) "-" noi di in gr "Symmetry | " in ye %9.4f `x2' /* */ _col(44) `df' _col(54) %5.4f `p' noi di in gr "Marginal homogeneity (MH) | " in ye %9.4f `m' /* */ _col(44) `df2' _col(54) %5.4f `p2' noi di in gr "MH no diagonals | " /* */ in ye %9.4f (`k'-1)*`mm'/`k' /* */ _col(44) `df3' _col(54) %5.4f `p3' noi di in gr _dup(26) "-" "+" _dup(33) "-" if "`exact'"=="exact" { noi di in gr "Symmetry (exact significance probability) " /* */ in ye _col(54) %5.4f pval } zap_s global S_1=`totpair' global S_2= `x2' global S_3= `df' global S_4= `p' global S_5= `m' global S_6= `df2' global S_7= `p2' global S_8= (`k'-1)*`mm'/`k' global S_9= `df3' global S_10= `p3' global S_11=pval } end program define mcross version 3.1 if "`1'" != "using" { noi di in red "using required" exit 198 } mac shift local nob = _N local using "`*'" tempfile cross2 tempvar order midx preserve quietly use "`using'", clear quietly { gen long `order'=_n expand `nob', clear sort `order' by `order': gen long `midx' = _n sort `midx' `order' drop `order' save "`cross2'", replace restore, preserve gen long `midx' = _n sort `midx' merge `midx' using "`cross2'" drop `midx' _merge restore, not } end exit