*! runtest--test for runs above and below threshold STB-14: snp5 *! version 1.0.0 Sean Becketti July 1993 program define runtest version 3.0 local varlist "req max(1)" local in "opt pre" local options "Continuity Drop Mean Split Threshold(str)" parse "`*'" /* Determine usable sample. Quit if any interior missing values. */ if "`drop'"!="" { local sfn "$S_FN" tempfile user qui save `user' } capture { count if `varlist'!=. `in' if _result(1)==0 { di in re "no observations" exit 99 } if "`in'"=="" { local in "in f/l" } parse "`in'", parse(" /") local f "`2'" if "`f'"=="f" { local f = 1 } local l "`4'" if "`l'"=="l" { local l = _N } while (`varlist'[`f']==.) { local f = `f' + 1 } while (`varlist'[`l']==.) { local l = `l' - 1 } local in "in `f'/`l'" count if `varlist'!=. `in' local N = _result(1) if `N'<2 { noi di in re "need at least 2 obs, you have `N'" error 99 } if (`N'<(`l'-`f'+1)) { noi di in re "`varlist' has missing observations" error 99 } /* Calculate run test. First calculate the threshold. By default, use the median. If the mean option is specified, use the mean instead. If the mean option is not specified, but the threshold option, use the threshold expression. */ tempvar thresh sum `varlist' `in', d local thresh = _result(10) if "`mean'"!="" { local thresh = _result(3) } else if "`thresho'"!="" { local thresh = `thresho' } /* Now create a binary variable for the "heads" and "tails". By default, values exactly equal to the threshold are counted as below the threshold. If the drop option is specified, equal values are dropped. If the split option is specified, equal values are randomly split between above and below. */ tempvar sign equal adjust if ("`drop'"!="" | "`split'"!="") { gen byte `equal' = `varlist'==`thresh' `in' if "`split'"!="" { /* split option */ local Nequal = 0 gen byte `adjust' = uniform()<.5 if `equal' `in' } else { /* drop option */ count if `equal' local Nequal = _result(1) if `Nequal'>0 { drop if `equal' `in' local l = `l' - `Nequal' local in "in `f'/`l'" local N = `N'-`Nequal' if `N'<2 { noi di in re "need at least 2 obs, you have `N'" error 99 } } gen byte `adjust' = 0 if `equal' `in' } } else { /* default */ local Nequal = 0 gen byte `equal' = 0 `in' gen byte `adjust' = 0 `in' } gen byte `sign' = cond(!`equal',`varlist'>`thresh',`adjust') `in' sum `varlist' tempvar runs gen long `runs' = 0 `in' local two = `f' + 1 replace `runs' = `sign'!=`sign'[_n-1] in `two'/`l' replace `runs' = sum(`runs') `in' local nruns = 1 + `runs'[`l'] count if !`sign' `in' local n0 = _result(1) count if `sign' `in' local n1 = _result(1) local x = 2*`n0'*`n1' local mean = 1 + `x'/(`N') local var = `x'*(`x'-`N')/(`N'^2 * (`N'-1)) local cc = cond("`continu'"=="",0,0.5) local zz = (`nruns'-`mean'+`cc')/sqrt(`var') local z = int(100*`zz'+.05)/100 local pp = 2*normprob(-abs(`zz')) local p = int(100*`pp'+.05)/100 noi di in gr " N(" in ye "`varlist'" in gr " <= " in ye "`thresh'" in gr ") = " in ye "`n0'" noi di in gr " N(" in ye "`varlist'" in gr " > " in ye "`thresh'" in gr ") = " in ye "`n1'" noi di in gr _skip(9) "obs = " in ye "`N'" noi di in gr _skip(5) "N(runs) = " in ye "`nruns'" noi di in gr _skip(10) "z = " in ye "`z'" noi di in gr _skip(7) "P>|z| = " in ye "`p'" mac def S_1 = `N' mac def S_2 = `nruns' mac def S_3 = `n0' mac def S_4 = `n1' mac def S_5 = `mean' mac def S_6 = `var' mac def S_7 = `zz' mac def S_8 = `pp' } local rc = _rc if "`drop'"!="" { if `Nequal'!=0 { qui use `user', clear mac def S_FN "`sfn'" } erase `user' } error `rc' end