*! version 1.1.7 feb2020. ***** Changelog *1.1.7 restore results of original estimation *1.1.6 fixes for spaces in filenames *1.1.5 some fixes for filenames *1.1.4 Added the reject() option, works as in permute *1.1.3 Updated version statement, because older versions (11) of Stata couldn't handle some of the code *1.1.2 Fixed the issue that data sanity checks were applied to the full sample, even if and [if] or [in]-statement was used to restrict analysis to a subsample. h/t fred finan *1.1.0 added a new option "fixlevels" to contstraint he rerandomization to certain levels of the treatment variable *1.0.9 added the strict and the eps option to the helpfile and added parameter-checks so that "strict" enforces "eps(0)". h/t Katharina Nesselrode *1.0.8 fixed (removed `') the "replace" option for the postfile statement as it was causing trouble when running ritest in wine and also I deactivated google analytics tracking *1.0.7 made sure that string cluster-identifiers are also treated correctly. *1.0.6 fixed an error message that appeared when the "saveresampling()" option was used. h/t Jason Kerwin *1.0.5 sped up the execution time for the permutation commmand (permute_simple) by dropping unneeded parts *1.0.5 made sure that string strata-identifiers are also treated correctly. *1.0.4 fixed the missing ",stable" for a sort in permute_simple, as suggested by david mckenzie. *1.0.3 hide the warnings introduced with 1.0.1, as requested by stata jounral *1.0.2 "if" and "in" for the subcommand will now be considered irrespective of "drop" or "nodrop" are specified *1.0.1 now can be called with the option RANDOMIZATIONProgram OR SAMPLINGprogram /* just some sample code i sometimes use for debuggin set seed 2 clear set obs 40 gen cluster=_n gen tr = mod(_n,2) expand 20 replace tr=2 if rnormal()>3 gen y = rnormal()+tr*0.01 reg y tr ritest tr _b[tr], cluster(cluster) seed(1): reg y tr if tr!=2 ritest tr r(rho), cluster(cluster) seed(1): corr y tr if tr!=2 */ cap program drop ritest cap program drop RItest cap program drop permute_extfile cap program drop permute_simple cap program drop rit_Results cap program drop rit_GetResults cap program drop rit_DisplayResults cap program drop rit_GetEvent cap program drop rit_TableFoot cap program drop ClearE program ritest version 13 set prefix ritest capture syntax [anything] using [, * ] if !c(rc) { if _by() { error 190 } Results `0' exit } quietly ssd query if (r(isSSD)) { di as err " not possible with summary statistic data" exit 111 } preserve `version' RItest `0' end program RItest, rclass version 13 local ritestversion "1.1.4" // get name of variable to permute gettoken resampvar 0 : 0, parse(" ,:") confirm variable `resampvar' unab resampvar : `resampvar' // : _on_colon_parse `0' local command `"`s(after)'"' local 0 `"`s(before)'"' syntax anything(name=exp_list /// id="expression list" equalok) /// [fw iw pw aw] [if] [in] [, /// FORCE /// Level(passthru) /// * /// other options ] if "`weight'" != "" { local wgt [`weight'`exp'] } // parse the command and check for conflicts // check all weights and stuff `version' _prefix_command ritest `wgt' `if' `in' , /// `efopt' `level': `command' if "`force'" == "" & `"`s(wgt)'"' != "" { // ritest does not allow weights unless force is used local 0 `s(wgt)' syntax [, NONOPTION ] } local version `"`s(version)'"' local cmdname `"`s(cmdname)'"' local cmdargs `"`s(anything)'"' local wgt `"`s(wgt)'"' local wtype `"`s(wtype)'"' local wexp `"`s(wexp)'"' local cmdopts `"`s(options)'"' local rest `"`s(rest)'"' local efopt `"`s(efopt)'"' local level `"`s(level)'"' local command `"`s(command)'"' local ifin `"`s(if)' `s(in)'"' //now check the options local 0 `", `options'"' syntax [, /// noDOTS /// lessdots /// not documented, only displays 1/10 dots Reps(integer 100) /// SAving(string) /// SAVEResampling(string) /// save resampvar for every round SAVERAndomization(string) /// synonym for the above DOUBle /// not documented (handles double precision) STRata(varlist) /// CLUster(varlist) /// FIXlevels(string) /// SEED(string) /// EPS(real 1e-7) /// -Results- options SAMPLINGSourcefile(string) /// RANDOMIZATIONSourcefile(string) ///syno ^ SAMPLINGMatchvar(varlist) /// RANDOMIZATIONMatchvar(string) ///syno ^ SAMPLINGProgram(name) /// RANDOMIZATIONProgram(string) ///syno ^ SAMPLINGPROGRAMOptions(string) /// RANDOMIZATIONPROGRAMOptions(string) ///syno ^ null(string) /// REJECT(string asis) /// NOIsily /// "prefix" options LEft RIght /// STRict /// noHeader /// not documented noLegend /// not documented NOANALYtics /// now obsolete COLLApse /// not documented an not recommendet KDENSityplot /// KDENSITYOptions(string) /// not documented * /// ] _get_diopts diopts, `options' //this makes sure no false options are passed //AT version 1.0.3 I switched from calling things "Sampling*" to calling them "Randomization*". //The following is to create backwardscompatibility and to make sure the code doesnt need to be changed //as long as the errs are commented out, the different options are just synonyms if ("`saveresampling'"=="") { local saveresampling `saverandomization' } else { //di as err "You're using deprecated syntax -saveresampling-, please use -saverandomization- instead" } if ("`samplingsourcefile'"=="") { local samplingsourcefile `"`randomizationsourcefile'"' } else { //di as err "You're using deprecated syntax -samplingsourcefile-, please use -randomizationsourcefile- instead" } if ("`samplingmatchvar'"=="") { local samplingmatchvar `randomizationmatchvar' } else { //di as err "You're using deprecated syntax -samplingmatchvar-, please use -randomizationmatchvar- instead" } if ("`samplingprogram'"=="") { local samplingprogram `randomizationprogram' } else { //di as err "You're using deprecated syntax -samplingprogram-, please use -randomizationprogram- instead" } if ("`samplingprogramoptions'"=="") { local samplingprogramoptions `randomizationprogramoptions' } else { //di as err "You're using deprecated syntax -samplingprogramoptions-, please use -randomizationprogramoptions- instead" } if (("`strata'" != "" | "`cluster'" != "" | `"`fixlevels'"' != "") + ("`samplingsourcefile'" != "" | "`samplingmatchvar'" != "") + ("`samplingprogram'" != "" | "`samplingprogramoptions'" != "") )>1 { di as err "Alternative sampling methods may not be combined." exit 198 } if "`saveresampling'"!="" { tempvar originalorder tempfile preservetemp tempfile resamplingtemp gen `originalorder'=_n qui save `"`resamplingtemp'"' } if "`strata'" == "" { tempvar strata gen `strata' = 1 local strata_orignal_varnames none } else { local strata_orignal_varnames "`strata'" } if "`cluster'" == "" { tempvar cluster gen `cluster' = _n } // set the seed if "`seed'" != "" { `version' set seed `seed' } local seed `c(seed)' if "`noisily'" != "" { local dots nodots } local nodots `dots' local dots = cond("`dots'" != "", "*", "_dots") local noi = cond("`noisily'"=="", "*", "noisily") if "`samplingsourcefile'"!="" { //check if samplingsourcefile is okay and sort preserve qui use `"`samplingsourcefile'"', clear qui sort `samplingmatchvar', stable qui desc if (r(k)-1)<`reps' { di as err "Permutation dataset does not contain enough permutations to complete `reps' repetitions" exit 2001 } qui save `"`samplingsourcefile'"', replace restore } // preliminary parse of _prefix_explist `exp_list', stub(_pm_) local eqlist `"`s(eqlist)'"' local idlist `"`s(idlist)'"' local explist `"`s(explist)'"' local eexplist `"`s(eexplist)'"' _prefix_note `cmdname', `nodots' `noi' di as inp `". `command'"' if "`noisily'" != "" { di "ritest: First call to `cmdname' with data as is:" _n } // run the command using the entire dataset (for output) //this needs to be done before the data set is altered to account for `null' `noisily' `command' //mark the sample to be used tempvar touse mark `touse' `ifin' preserve //this will only be restored in the very end if ("`null'"!="") { di as text "User specified non-zero null hypothesis" local vari : word 1 of `null' local valu : word 2 of `null' capture confirm variable `vari' if (_rc != 0) { di as err "Hypotheses seem to be misspecified, `vari' is not a variable in the current data set" exit 9 } cap confirm number `valu' if (_rc!=0) { capture confirm variable `valu' } if (_rc != 0) { di as err "Hypotheses seem to be misspecified, second argument to hypothesis has to be numeric or a varialbe name" exit 9 } di as text "Under the null hypothesis:" di as text " `vari' has treatment effect: `resampvar'*`valu'" qui replace `vari' = `vari' - `resampvar'*`valu' di as text " (these values are being subtracted from the outcome)" } _prefix_clear, e r // run the command using the entire dataset (to get the estimate) aftera imposing `null' qui `noisily' /// `command' tempname originalestimates est store `originalestimates' // check for rejection of results from entire dataset if `"`reject'"' != "" { _prefix_reject ritest `cmdname' : `reject' local reject `"`s(reject)'"' } // expand eexp's that may be in eexplist, and build a matrix of the // computed values from all expressions tempname b _prefix_expand `b' `explist', /// stub(_pm_) /// eexp(`eexplist') /// colna(`idlist') /// coleq(`eqlist') /// local k_eq `s(k_eq)' local k_exp `s(k_exp)' //number of expressions local k_eexp `s(k_eexp)' //number of eexpressions local K = `k_exp' + `k_eexp' //number of expression + eexprsessions local k_extra `s(k_extra)' local names `"`s(enames)' `s(names)'"' local coleq `"`s(ecoleq)' `s(coleq)'"' local colna `"`s(ecolna)' `s(colna)'"' forval i = 1/`K' { local exp`i' `"`s(exp`i')'"' } // setup list of missings forvalues j = 1/`K' { local mis `mis' (.) if missing(`b'[1,`j']) { di as err /// `"'`exp`j''' evaluated to missing in full sample"' exit 322 } } local ropts eps(`eps') /// `left' `right' /// `strict' /// level(`level') /// `header' /// `verbose' /// `title' /// `table' /// `diopts' // check options if `reps' < 1 { di as err "reps() must be a positive integer" exit 198 } if `"`saving'"'=="" { tempfile saving local filetmp "yes" } else { _prefix_saving `saving' local saving `"`s(filename)'"' if "`double'" == "" { local double `"`s(double)'"' } local replace `"`s(replace)'"' } if `"`fixlevels'"' != "" { tempvar fixedvalues_indicator qui gen `fixedvalues_indicator'=. local ccc 0 foreach value of local fixlevels { qui sum `resampvar' if `resampvar'==`value' & `touse' if r(N)==0 { di as err "you specified to hold observations with `resampvar'==`value' fixed, but it seems there are no such observations" } else { qui replace `fixedvalues_indicator' = `ccc++' if `resampvar'==`value' } } } if `"`strata'"' != "" { if `:list resampvar in strata' { di as err "permutation variable may not be specified in strata() option" exit 198 } //I replace strata by single varialbe to simply computation and tempvar strata_ egen `strata_' = group(`strata' `fixedvalues_indicator'), missing if `"`fixlevels'"' != "" { local strata_orignal_varnames `"`strata_orignal_varnames' (created separate strata for `resampvar'-values: `fixlevels')"' } local strata `strata_' tempvar sflag markout `touse' `strata', strok sort `touse' `strata', stable by `touse' `strata': gen `sflag' = _n==1 if `touse' qui replace `sflag' = sum(`sflag') local nstrata = `sflag'[_N] local ustrata `strata' local strata `sflag' sort `strata' , stable qui loneway `resampvar' `strata' if `touse' if (r(sd_w) == 0){ di as err "Warning: some strata contain no variation in `resampvar'" if `"`fixlevels'"' != "" { di as err "You specified fixlevels(`fixlevels'). This may be responsible for this warning and is not necessarily a problem." } } } if `"`cluster'"' != "" { if `:list resampvar in strata' { di as err "permutation variable may not be specified in strata() option" exit 198 } tempvar cflag markout `touse' `strata' `cluster' , strok sort `touse' `strata' `cluster' , stable by `touse' `strata' `cluster': gen `cflag' = _n==1 if `touse' qui replace `cflag' = sum(`cflag') local N_clust = `cflag'[_N] local clustvar `cluster' local cluster `cflag' sort `strata' `cluster', stable qui loneway `resampvar' `cflag' if `touse' if (r(sd_w) != 0 & !missing(r(sd_w))) { di as err "`resampvar' does not seem to be constant within clusters" exit 9999 } } local obs = _N local method 0 if "`samplingsourcefile'"!="" | "`samplingmatchvar'"!="" { local method extfile } else if "`samplingprogram'"!="" { local method program cap program list `samplingprogram' if _rc!=0 { di as err "proceedure -`samplingprogram'- does not exists" exit 198 } } else { local method permute } if `eps' < 0 { di as err "eps() must be greater than or equal to zero" exit 198 } if "`strict'"!="" { if `eps' > 0 { di as err "Warning: if the strict option is specified, eps must be set to 0 using -eps(0)" exit 198 } } // temp variables for post local stats forvalues j = 1/`K' { //fore each expression generate a tempvar tempname x`j' local stats `stats' (`b'[1,`j']) local xstats `xstats' (`x`j'') } // prepare post tempname postnam qui postfile `postnam' `names' using `"`saving'"', /// `double' `every' replace post `postnam' `stats' //methods such as "external file" or "automatic permuations" are wrapped in the third one if "`method'"=="permute" { local samplingprogram permute_simple local samplingprogramoptions "strata(`strata') cluster(`cluster')" } else if "`method'"=="extfile" { local samplingprogram permute_extfile local samplingprogramoptions `"file(`"`samplingsourcefile'"') matchvars(`samplingmatchvar')"' } if ("`noanalytics'"=="") { //This was the GOOGLE-ANALYTICS bit } else { di as err "you specified noanalytics option. The google analytics tracking has been removed from the code permantly" } if "`dots'" == "*" { local noiqui noisily quietly } // do permutations if "`nodots'" == "" | "`noisily'" != "" { di `dots' 0, title(Resampling replications) reps(`reps') `nodots' } local rejected 0 forvalues i = 1/`reps' { //for debugging: display seed //noi noi noi di as err substr(c(rngstate), 4996,.) cap `samplingprogram', run(`i') resampvar(`resampvar') `samplingprogramoptions' if _rc!=0 { di as err "Failed while calling resampling proceedure. Call was: " _n "{stata `samplingprogram', run(`i') resampvar(`resampvar') `samplingprogramoptions'}" _n as text "Error was: " error _rc } if "`saveresampling'"!="" { qui save `"`preservetemp'"',replace rename `resampvar' `resampvar'`i' cap qui merge 1:1 `originalorder' using `"`resamplingtemp'"', nogen rename `originalorder' keep`originalorder' drop __* rename keep`originalorder' `originalorder' cap order `resampvar'* , last qui save `"`resamplingtemp'"', replace use `"`preservetemp'"', clear } // analyze permuted data `noi' di as inp `". `command'"' capture `noiqui' `noisily' `command' if (c(rc) == 1) error 1 local bad = c(rc) != 0 if c(rc) { `noi' di in smcl as error `"{p 0 0 2}an error occurred when I executed `cmdname', "' /// `"posting missing values{p_end}"' post `postnam' `mis' } else { if `"`reject'"' != "" { capture local rejected = `reject' if c(rc) { local rejected 1 } } if `rejected' { local bad 1 `noi' di as error /// `"{p 0 0 2}rejected results from `cmdname', "' /// `"posting missing values{p_end}"' post `postnam' `mis' } else { forvalues j = 1/`K' { capture scalar `x`j'' = `exp`j'' if (c(rc) == 1) error 1 if c(rc) { local bad 1 `noi' di in smcl as error /// `"{p 0 0 2}captured error in `exp`j'', posting missing value{p_end}"' scalar `x`j'' = . } else if missing(`x`j'') { local bad 1 } } post `postnam' `xstats' } } if "`lessdots'"=="" { `dots' `i' `bad' } else if mod(`i',10)==0 { if mod(`i',500)==0 { `dots' `i' `bad' } else { `dots' 4 `bad' } } } `dots' `reps' // cleanup post postclose `postnam' if `"`saveresampling'"'!="" { cp "`resamplingtemp'" `"`saveresampling'"' } // load file `saving' with permutation results and display output capture use `"`saving'"', clear if c(rc) { if c(rc) >= 900 & c(rc) <= 903 { di as err "insufficient memory to load file with permutation results" } error c(rc) } if ("`collapse'" != "") { di as err "collapsing" gen uh=0 collapse uh,by(_*) drop uh } label data `"ritest `resampvar' : `cmdname'"' // save permute characteristics and labels to data set forvalues i = 1/`K' { local name : word `i' of `names' local x = `name'[1] char `name'[permute] `x' local label = substr(`"`exp`i''"',1,80) label variable `name' `"`label'"' char `name'[expression] `"`exp`i''"' if `"`coleq'"' != "" { local na : word `i' of `colna' local eq : word `i' of `coleq' char `name'[coleq] `eq' char `name'[colname] `na' if `i' <= `k_eexp' { char `name'[is_eexp] 1 } } } if ("`kdensityplot'" != "") { foreach var of varlist * { qui sum `var' in 1, meanonly local realization=r(mean) local kopt=subinstr(`"`kdensityoptions'"',"{realization}","`realization'",.) kdensity `var' in 2/-1, xline(`realization') name(`var', replace) graphregion(color(white)) `kopt' } } char _dta[k_eq] `k_eq' char _dta[k_eexp] `k_eexp' char _dta[k_exp] `k_exp' char _dta[N_strata] `nstrata' char _dta[N_clust] `N_clust' char _dta[seed] "`seed'" char _dta[strata] `ustrata' char _dta[strata_orignal_varnames] `"`strata_orignal_varnames'"' char _dta[clustvar] `clustvar' char _dta[N] `obs' char _dta[resampvar] "`resampvar'" char _dta[command] "`command'" char _dta[sampling_method] "`method'" quietly drop in 1 if `"`filetmp'"' == "" { quietly save `"`saving'"', replace } ClearE qui est restore `originalestimates' rit_Results, `ropts' return add return scalar N_reps = `reps' end program permute_simple syntax , strata(varname) cluster(varname) resampvar(varname) * tempvar ind nn newt rorder //create a random variable gen `rorder'=runiform() qui { //mark first obs in each cluster, for those i will perform the permutations sort `strata' `cluster', stable by `strata' `cluster': gen `ind' = 1 if _n==1 //across all first observations within clusters, save their position in the data set sort `strata' `ind', stable by `strata' `ind': gen `nn'=_n if `ind'!=. //now, reshuffle these first observations within strata, take the treatment status from the observation which was at this position before sort `strata' `ind' `rorder', stable by `strata' `ind': gen `newt'=`resampvar'[`nn'] //place the first observations on top of each cluster //copy the treatment status to all observations in the same cluster sort `strata' `cluster' `ind', stable by `strata' `cluster': replace `newt'=`newt'[_n-1] if missing(`newt') //clean up drop `resampvar' `nn' `ind' `rorder' rename `newt' `resampvar' } end program permute_extfile syntax ,file(string) matchvars(varlist) run(integer) resampvar(varlist) sort `matchvars', stable cap isid `matchvars' if c(rc) { capture qui merge m:1 `matchvars' using `"`file'"', keepusing(`resampvar'`run') nogen if c(rc) { di as err "`resampvar'`run' does not exist in the permutation data set" } } else { capture qui merge 1:1 `matchvars' using `"`file'"', keepusing(`resampvar'`run') nogen if c(rc) { di as err "`resampvar'`run' does not exist in the permutation data set" } } drop `resampvar' rename `resampvar'`run' `resampvar' end program rit_Results //output the results in a nice table syntax [anything(name=namelist)] /// [using/] [, /// eps(real 1e-7) /// -GetResults- options left /// right /// strict /// TItle(passthru) /// Level(cilevel) /// -DisplayResults- options noHeader /// noLegend /// Verbose /// notable /// not documented * /// ] _get_diopts diopts, `options' if `"`using'"' != "" { preserve qui use `"`using'"', clear } else if `"`namelist'"' != "" { local namelist : list uniq namelist preserve } local 0 `namelist' syntax [varlist(numeric)] if "`namelist'" != "" { keep `namelist' local 0 syntax [varlist] } rit_GetResults `varlist', /// eps(`eps') /// `left' `right' `strict' /// level(`level') /// `title' rit_DisplayResults, `header' `table' `legend' `verbose' `diopts' end program rit_GetResults, rclass syntax varlist [, /// Level(cilevel) /// eps(real 1e-7) /// -GetResults- options left /// right /// strict /// TItle(string asis) /// ] // original number of observations local obs : char _dta[N] if "`obs'" != "" { capture confirm integer number `obs' if c(rc) { local obs } else if `obs' <= 0 { local obs } } // number of strata local nstrata : char _dta[N_strata] if "`nstrata'" != "" { capture confirm integer number `nstrata' if c(rc) { local nstrata } } // number of cluster local N_clust : char _dta[N_clust] if "`N_clust'" != "" { capture confirm integer number `N_clust' if c(rc) { local N_clust } } // strata variable if "`nstrata'" != "" { local strata_orignal_varnames : char _dta[strata_orignal_varnames] local strata : char _dta[strata] if "`strata'" != "" { capture confirm names `strata' if c(rc) { local strata } } } // cluster variable if "`N_clust'" != "" { local clustvar : char _dta[clustvar] if "`clustvar'" != "" { capture confirm names `clustvar' if c(rc) { local clustvar } } } // permutation method local sampling_method : char _dta[sampling_method] // permutation variable local resampvar : char _dta[resampvar] capture confirm name `resampvar' if c(rc) | `:word count `resampvar'' != 1 { local resampvar } if `"`resampvar'"' == "" { di as error /// "permutation variable name not present as data characteristic" exit 9 } // requested event rit_GetEvent, `left' `right' `strict' eps(`eps') local event `s(event)' local rel `s(rel)' local abs `s(abs)' local minus `"`s(minus)'"' tempvar diff //geqdiff gen `diff' = 0 local K : word count `varlist' tempname b c reps p se ci matrix `b' = J(1,`K',0) matrix `c' = J(1,`K',0) matrix `reps' = J(1,`K',0) matrix `p' = J(1,`K',0) matrix `se' = J(1,`K',0) matrix `ci' = J(1,`K',0) \ J(1,`K',0) local seed : char _dta[seed] local k_eexp 0 forvalues j = 1/`K' { local name : word `j' of `varlist' local value : char `name'[permute] capture matrix `b'[1,`j'] = `value' if c(rc) | missing(`value') { di as err /// `"estimates of observed statistic for `name' not found"' exit 111 } tempvar ties gen `ties' = (`abs'(`name') == `abs'(`value') ) qui sum `ties', meanonly if `r(mean)'>0.01 { noi noi di as err "Warning: `=round(100*r(mean))'% of the resampled realizations for `name' are exactly identical to original value" } quietly replace /// `diff' = (`abs'(`name') `rel' `abs'(`value') `minus' `eps') sum `diff' if `name'<., meanonly if r(N) < c(N) { local missing missing } mat `c'[1,`j'] = r(sum) mat `reps'[1,`j'] = r(N) quietly cii `=`reps'[1,`j']' `=`c'[1,`j']', level(`level') mat `p'[1,`j'] = r(mean) mat `se'[1,`j'] = r(se) mat `ci'[1,`j'] = r(lb) mat `ci'[2,`j'] = r(ub) local coleq `"`coleq' `"`:char `name'[coleq]'"'"' local colname `colname' `:char `name'[colname]' local exp`j' : char `name'[expression] if `"`:char `name'[is_eexp]'"' == "1" { local ++k_eexp } } local coleq : list clean coleq // command executed for each permutation local command : char _dta[command] local k_exp = `K' - `k_eexp' // put stripes on matrices if `"`coleq'"' == "" { version 11: matrix colnames `b' = `varlist' } else { version 11: matrix colnames `b' = `colname' if `"`coleq'"' != "" { version 11: matrix coleq `b' = `coleq' } } matrix rowname `b' = y1 _copy_mat_stripes `c' `reps' `p' `se' `ci' : `b', novar matrix rowname `ci' = ll ul matrix roweq `ci' = _ _ // Save results return clear if "`obs'" != "" { return scalar N = `obs' } return scalar level = `level' return scalar k_eexp = `k_eexp' return scalar k_exp = `k_exp' return matrix reps `reps' return matrix c `c' return matrix b `b' return matrix p `p' return matrix se `se' return matrix ci `ci' return hidden local seed `seed' return local rngstate `seed' return local missing `missing' return local resampvar `resampvar' if "`nstrata'" != "" { return scalar N_strata = `nstrata' if "`strata_orignal_varnames'" != "" { return local strata_orignal_varnames `"`strata_orignal_varnames'"' } if "`strata'" != "" { return local strata `strata' } } if "`N_clust'" != "" { return scalar N_clust = `N_clust' if "`clustvar'" != "" { return local clustvar `clustvar' } } return local event `event' return local left `left' return local right `right' return local strict `strict' forval i = 1/`K' { return local exp`i' `"`exp`i''"' } if `"`title'"' != "" { return local title `"`title'"' } else return local title "Monte Carlo results" return local command `"`command'"' return local sampling_method `"`sampling_method'"' return local cmd ritest end program rit_DisplayResults, rclass syntax [, /// noHeader /// noLegend /// Verbose /// notable /// * /// ] _get_diopts diopts, `options' if "`header'" == "" { //this is supposed to produce a nice header, but doesn't because _coef_table_header doesn't no ritest, so I do it manuallly //_coef_table_header, rclass _prefix_legend ritest, rclass `verbose' di as txt %`s(col1)'s "res. var(s)" ": `r(resampvar)'" if "`r(sampling_method)'"=="extfile" { di as txt %`s(col1)'s "Resampling" as text ": Using an external file" } else if "`r(sampling_method)'"=="program" { di as txt %`s(col1)'s "Resampling" as text ": Using a user-specified program" } else if "`r(sampling_method)'"=="permute" { di as txt %`s(col1)'s "Resampling" as text ": Permuting `r(resampvar)'" if !missing(r(N_clust)) & "`r(clustvar)'" != "" { di as txt %`s(col1)'s "Clust. var(s)" as res ": `r(clustvar)'" di as txt %`s(col1)'s "Clusters" as res ": `r(N_clust)'" } if !missing(r(N_strata)) & "`r(strata_orignal_varnames)'" != "" { di as txt %`s(col1)'s "Strata var(s)" as res ": `r(strata_orignal_varnames)'" di as txt %`s(col1)'s "Strata" as res ": `r(N_strata)'" } } else { di as txt %`s(col1)'s "Resampling" as text ": `sampling_method'" } } // NOTE: _coef_table_header needs the results in r() to work properly, // thus the following line happens here instead of at the very top. return add if ("`table'" != "") { exit } else if "`header'" == "" { di } tempname Tab results .`Tab' = ._tab.new, col(8) lmargin(0) ignore(.b) ret list // column 1 2 3 4 5 6 7 8 .`Tab'.width 13 |12 8 8 8 8 10 10 .`Tab'.titlefmt %-12s . . . . . %20s . .`Tab'.pad . 2 0 0 0 0 0 1 .`Tab'.numfmt . %9.0g . . %7.4f %7.4f . . local cil `=string(`return(level)')' local cil `=length("`cil'")' if `cil' == 2 { local cititle "Conf. Interval" } else { local cititle "Conf. Int." } // begin display .`Tab'.sep, top .`Tab'.titles "T" "T(obs)" "c" "n" "p=c/n" "SE(p)" /// "[`return(level)'% `cititle']" "" tempname b c reps p se ci matrix `b' = return(b) matrix `c' = return(c) matrix `reps' = return(reps) matrix `p' = return(p) matrix `se' = return(se) matrix `ci' = return(ci) local K = colsof(`b') local colname : colname `b' local coleq : coleq `b', quote local coleq : list clean coleq if `"`:list uniq coleq'"' == "_" { local coleq .`Tab'.sep } local error5 " (omitted)" local error6 " (base) " local error7 " (empty) " gettoken start : colname local ieq 0 local i 1 local output 0 local first // starts empty forvalues j = 1/`K' { local curreq : word `j' of `coleq' if "`curreq'" != "`eq'" { .`Tab'.sep di as res %-12s abbrev("`curreq'",12) as txt " {c |}" local eq `curreq' local i 1 local ++ieq } else if "`name'" == "`start'" { .`Tab'.sep } _ms_display, el(`i') eq(#`ieq') matrix(`b') `first' `diopts' if r(output) { local first if !`output' { local output 1 } } else { if r(first) { local first first } local ++i continue } local note `"`r(note)'"' local err 0 if "`note'" == "(base)" { local err 6 } if "`note'" == "(empty)" { local err 7 } if "`note'" == "(omitted)" { local err 5 } .`Tab'.width . 13 . . . . . ., noreformat if `err' { local note : copy local error`err' .`Tab'.row "" "`note'" .b .b .b .b .b .b } else { .`Tab'.row "" /// `b'[1,`j'] /// `c'[1,`j'] /// `reps'[1,`j'] /// `p'[1,`j'] /// `se'[1,`j'] /// `ci'[1,`j'] /// `ci'[2,`j'] /// // blank } .`Tab'.width . |12 . . . . . ., noreformat local ++i } .`Tab'.sep, bottom rit_TableFoot "`return(event)'" `K' `return(missing)' end program ClearE, eclass ereturn clear end program rit_GetEvent, sclass sret clear syntax [, left right strict eps(string)] if "`left'"!="" & "`right'"!="" { di as err "only one of left or right can be specified" exit 198 } local unstrict if "`strict'"=="" { local unstrict="=" } if "`left'"!="" { sreturn local event "T <`unstrict' T(obs)" sreturn local rel "<`unstrict'" sreturn local minus "+" } else if "`right'"!="" { sreturn local event "T >`unstrict' T(obs)" sreturn local rel ">`unstrict'" sreturn local minus "-" } else { sreturn local event "|T| >`unstrict' |T(obs)|" sreturn local rel ">`unstrict'" sreturn local abs "abs" sreturn local minus "-" } end program rit_TableFoot args event K missing if `K' == 1 { di as txt /// "Note: Confidence interval is with respect to p=c/n." } else { di as txt /// "Note: Confidence intervals are with respect to p=c/n." } if "`event'"!="" { di in smcl as txt "Note: c = #{`event'}" } if "`missing'" == "missing" { di as txt /// "Note: Missing values observed in permutation replicates." } end exit