program define tabout8 * for use with Stata 8.2 * replaced by tabout 30nov2006 (requires Stata 9.2) * 1.2.0 Ian Watson 13mar2005 * 1.1.8 Ian Watson 30nov2004 * 1.1.0 Ian Watson 28oct2004 * Program to produce publication quality cross-tabulations version 8.2 syntax varlist [if] [in] [fweight aweight iweight] using/ /// [, REPlace APPend Cells(string) oneway Format(string) /// stats(string) n(string) /// style(string) lines(string) font(string) bt NOBORDer /// total(string) header1(string) header2(string) header3(string) /// LEFTHead(string) NOHEADer NOTOTals(string) /// body topf(string) botf(string) topstr(string) botstr(string) /// PSYMBol(string) DELIM(string) /// show(string) LABWidth(int 20) COLWidth(int 11) TABWidth(string)] tempvar touse mark `touse' `if' `in' local varcnt : word count `varlist' * store existing linesize for resetting on exit global oldsize=c(linesize) * set defaults for key macros local sstats 0 local dstats 0 global dpanel 0 local fcnt 0 local fper 0 local fcum 0 local content 3 // default for cross-tabulations global nogood 0 local skip 1 local do_N 0 local do_Nc 0 local do_Nl 0 * check parsing and set defaults * note that only first term in summary stats is checked here * remainders are checked within the sstats loop if "`cells'" ~= ""{ local fword : word 1 of `cells' if index("double row col count fcount fper fcum","`fword'") ~= 0 { local sstats 0 if index("`cells'","fcount") ~= 0 local fcnt 1 if index("`cells'","fper") ~= 0 local fper 1 if index("`cells'","fcum") ~= 0 local fcum 1 if index("`cells'","double") ~= 0 global dpanel 1 if index("`cells'","row") ~= 0 local content 1 if index("`cells'","col") ~= 0 local content 2 if index("`cells'","count") ~= 0 local content 3 } * following lines need splitting because of Intercooled string limits else if /// index("N mean var sd skewness kurtosis sum min max","`fword'") ~= 0 | /// index("p1 p5 p10 p25 p50 p75 p90 p95 p99","`fword'") ~= 0 | /// index("count median iqr r9010 r9050 r7525 r1050","`fword'") ~= 0 { local sstats 1 local numstats : word count `cells' local numstats = `numstats'/2 // because each stat is paired with a var if index("iqr r9010 r9050 r7525 r1050","`fword'") ~= 0 local dstats 1 } else { di as err "The first term you entered in the cells option is incorrect" clearglobs exit } } if `fcnt' == 0 & `fper' == 0 & `fcum' == 0 local fcnt 1 // default for freq tables * note sstats is summary stats * dstats is distribution stats, a subset of sstats if "`oneway'"~="" { local crtabs 0 if `sstats' == 1 { local stwidth = `numstats' local fstwidth = `numstats' +1 } } else { if `varcnt' > 1 local crtabs 1 else local crtabs 0 if `sstats' == 1 { local stwidth = `numstats' local fstwidth = `numstats' +1 } } if "`stats'"~="" { local chiword1: word 1 of `stats' if "`chiword1'" == "chi2" { if `varcnt'~=2 | `crtabs'~=1 { di as err "Chi2 only possible with simple two-way tables." di as err "You either have more than 2 variables," di as err "or you have specified the oneway option." clearglobs exit } else { local dochi=1 local chiword = "chi2" local chistr = "" local chiword2: word 2 of `stats' if "`chiword2'" ~= "" local chidec `chiword2' else local chidec 3 local chiword3: word 3 of `stats' if "`chiword2'" ~= "" local pdec `chiword3' else local pdec 3 } } else { di di as err "The exact term chi2 is the only acceptable term" di as err "for the stats option. No statistics will be processed." di local dochi=0 } } else local dochi=0 * check that all variable values have labels local warnlist1="" local warnlist2="" foreach v of local varlist { local var_label : variable label `v' local val_label : value label `v' if "`var_label'" =="" { local warnlist1 = "`warnlist1' `v'" } if "`val_label'" =="" { local warnlist2 = "`warnlist2' `v'" } } if "`warnlist1'" ~= "" | "`warnlist2'" ~= ""{ if "`warnlist1'" ~= "" { di di as err "Variable(s) `warnlist1' without variable labels." di as err "All variables must have labels." di } if "`warnlist2'" ~= "" { di di as err "Variable(s) `warnlist2' without value labels." di as err "All variables must have value labels." di } clearglobs exit } if "`append'" == "append" { local opt "append" } else if "`replace'" == "replace" { local opt "replace" } * parse remaining syntax and assign to macros * note the use of some global macros because of sub-routines if `crtabs' == 0 { if `varcnt' == 1 local single 1 else local single 0 } else { if `varcnt' == 2 local single 1 else local single 0 } if "`format'" ~= "" { local numforms: word count `format' if `numforms' == 1 { local form "`format'" global form "`format'" } else { local form : word 1 of `format' global form : word 1 of `format' global form1 : word 1 of `format' global form2 : word 2 of `format' } } else { local numforms 1 local format "%9.0fc" local form "%9.0fc" global form "%9.0fc" global form1 "%9.0fc" global form2 "%9.1f" } if "`delim'" ~= "" { global dl "`delim'" } else { global dl "|" } if "`n'"~="" { tokenize "`n'", parse("$dl") local Nloc `1' if "`Nloc'" ~= "" { if "`Nloc'" == "col" | "`Nloc'" == "lab" { local Nform "%9.0fc" local do_N 1 if "`Nloc'"=="col" local do_Nc 1 else if "`Nloc'"=="lab" local do_Nl 1 } else { di as err "Only col or lab can be entered for location." clearglobs exit } } local Nlabel `3' if "`Nloc'"=="col" { if "`Nlabel'" == "d" local Nlabel "n" else local Nlabel = subinstr("`Nlabel'"," ","_",.) } else if "`Nloc'"=="lab" { if "`Nlabel'" == "d" { local Nlab1 "(n_=_" local Nlab2 ")" } else { local Nlabel = subinstr("`Nlabel'"," ","_",.) local p = index("`Nlabel'","#") local q = length("`Nlabel'") local Nlab1 = substr("`Nlabel'",1,`p'-1) local Nlab2 = substr("`Nlabel'",`p'+1,`q'-`p') } } local Nwt `5' if "`Nwt'" == "d" local Nweight "" else local Nweight "[iweight = `Nwt']" } if "`total'" ~="" { tokenize "`total'", parse("$dl") local vword `1' local hword `3' } else { local hword = "Total" local vword = "Total" } if "`show'" ~= "" { if "`show'" =="all" { local scr 1 local cod 1 } else if "`show'" == "table" { local scr 1 local cod 0 } else if "`show'" == "code" { local scr 0 local cod 1 } else if "`show'" == "none" { local scr 0 local cod 0 } } else { local scr 1 local cod 0 } local rule = cond("`bt'" ~= "", "\\midrule", "\\hline") local bcode = cond("`body'" ~= "", 1, 0) local border = cond("`noborder'" ~= "", "", " border=3") if "`lines'" ~= "" { if "`lines'" == "double" { local lspace 2 } else if "`lines'" == "blank" { local lspace 3 } else if "`lines'" == "none" { local lspace 0 } else local lspace 1 } else local lspace 1 * lefthead moves vertical var lab up & down within headers - default is empty if "`lefthead'"~="" { if index("1 2 3","`lefthead'") ~= 0 local lefthd "`lefthead'" else local lefthd "" } else local lefthd "" if "`font'" ~= "" { if "`font'" == "bold" local tfont "bold" else if "`font'" == "italic" local tfont "italic" else local tfont "plain" } else local tfont "plain" local prefile = cond("`topf'" ~= "", "`topf'" , "") local postfile = cond("`botf'" ~= "", "`botf'", "") local topinsert = cond("`topstr'" ~= "", "`topstr'", "") local botinsert = cond("`botstr'" ~= "", "`botstr'", "") * no default for ps b/c its contents signals entry into loop later global ps = cond("`psymbol'" ~= "", "`psymbol'", "") local dotop = cond("`topinsert'" ~= "" & "$ps" ~= "", 1, 0) local dobot = cond("`botinsert'" ~= "" & "$ps" ~= "", 1, 0) if "`header1'" ~="" local topstring1 = "`header1'" if "`header2'" ~="" local topstring2 = "`header2'" if "`header3'" ~="" local topstring3 = "`header3'" local blankhead = cond("`noheader'" ~= "", 1, 0) if "`nototals'" ~= "" { local dotot 0 local glbtot "`nototals'" } else { local dotot 1 local glbtot "" } * set tab delimitted as default output if "`style'" ~= "" { if "`style'" == "tex" { local out 1 } else if "`style'" == "html" { local out 2 } else if "`style'" == "tab" { local out 3 } else { local out 3 } } else local out 3 * tablewidth is string, not integer, so that can be left * alone if need be if "`tabwidth'" ~= "" { local tabw = "`tabwidth'" set linesize `tabw' } else { local tabw = "" } * other widths are integers, only need for screen display local labw = min(max(`labwidth',8),60) local gap=min(max(`colwidth',6),30) local dgap = `gap'*2 * PROGRAM PROPER BEGINS HERE * fill the matrices with tabulate results local nvars : word count `varlist' local hvar : word `nvars' of `varlist' local hlen=length("`hvar'") local vlen=length("`varlist'")-(`hlen'+1) local vvar=substr("`varlist'",1,`vlen') * check first for maximum number of values in the * horizontal variable - needed for cross-tabulation stacked tables qui ta `hvar' `hvar' [`weight' `exp'] if `touse', matcol(hvals) local lgesize = colsof(hvals) * tables for tables which are not summary stats * one-wayfrequency tables if `sstats' == 0 { if `crtabs' == 0 { local vcnt=0 foreach v of local varlist { local vcnt=`vcnt'+1 qui ta `v' [`weight' `exp'] if `touse', matcell(newmat) /// matrow(newrow) local valnames = "" local labelname : value label `v' local r = rowsof(newmat) local l = `r' + 1 mat labs = J(`l',1,-9) mat counts = J(`l',1,0) mat percents = J(`l',1,0) mat cums = J(`l',1,0) local countsum = 0 forval z = 1/`r'{ mat counts[`z',1] = newmat[`z',1] local countsum = `countsum' + newmat[`z',1] mat labs[`z',1] = newrow[`z',1] } mat counts[`l',1] = `countsum' forval z = 1/`r'{ mat percents[`z',1] = counts[`z',1]/`countsum'*100 if `z' == 1 { mat cums[`z',1] = percents[`z',1] } else { mat cums[`z',1] = percents[`z',1] + cums[`z'-1,1] } } mat percents[`l',1] = 100 mat cums[`l',1] = . mat freq = labs,counts,percents,cums if `vcnt' == 1 mat full = freq else mat full = full\freq } // end foreach var } // if crtabs == 0 else { *begin cross-tabulations local vcnt=0 foreach v of local vvar{ local vcnt=`vcnt'+1 qui ta `v' `hvar' [`weight' `exp'] if `touse', matcell(newmat) /// matrow(newrow) matcol(newcol) `chiword' if `do_N' qui ta `v' `hvar' `Nweight' if `touse', matcell(Nmat) if `dochi' == 1 { local df = (r(r)-1)*(r(c)-1) local chival = string(r(chi2),"%9.`chidec'f") local pval = string(r(p),"%9.`pdec'f") local chistr "Pearson chi-square (`df' df) =" /// " `chival', probability = `pval'" } local valnames = "" local labelname : value label `v' local r = rowsof(newmat) local c = colsof(newmat) local l = `lgesize' local j = colsof(newcol) mat counts = J(`r',`l',0) mat Ncounts = J(`r',`l',0) mat rownumber = J(`r',1,0) mat colnumber = J(1,`l',-9) mat rowtot = J(`r',1,0) mat Nrowtot = J(`r',1,0) forval z = 1/`r'{ local y = 1 while `y' < (`j'+1) { forval x = 1/`l'{ if newcol[1,`y'] == hvals[1,`x'] { if newmat[`z',`y'] == . mat counts[`z',`x'] = 0 else mat counts[`z',`x'] = newmat[`z',`y'] if `do_N' mat Ncounts[`z',`x'] = Nmat[`z',`y'] local y = `y'+1 } } } } local c = `l' local finalw = `c'+1 mat coltot = J(1,`finalw',0) mat Ncoltot = J(1,`finalw',0) forval z=1/`r'{ forval x=1/`c'{ mat rowtot[`z',1] = rowtot[`z',1] + counts[`z',`x'] if `do_N' mat Nrowtot[`z',1] = Nrowtot[`z',1] + Ncounts[`z',`x'] mat coltot[1,`x'] = coltot[1,`x'] + counts[`z',`x'] if `do_N' mat Ncoltot[1,`x'] = Ncoltot[1,`x'] + Ncounts[`z',`x'] } mat coltot[1,`finalw']= coltot[1,`finalw'] + rowtot[`z',1] if `do_N' mat Ncoltot[1,`finalw']= Ncoltot[1,`finalw'] + Nrowtot[`z',1] } mat wider = counts,rowtot mat longer = wider\coltot mat cellcnt = longer if `do_N' { mat Nwider = Ncounts,Nrowtot mat Nlonger = Nwider\Ncoltot mat Ncellcnt = Nlonger } * matrix with cell counts complete * convert to percentages local r = rowsof(cellcnt) local c = colsof(cellcnt) mat colp = J(`r',`c',0) forval z = 1/`r'{ forval x = 1/`c'{ if cellcnt[`r',`x'] ~= 0 { mat colp[`z',`x'] = cellcnt[`z',`x']/cellcnt[`r',`x']*100 } else { mat colp[`z',`x'] = 0 } } } mat rowp=J(`r',`c',0) forval z=1/`r'{ forval x=1/`c'{ if cellcnt[`z',`c'] ~= 0 { mat rowp[`z',`x']=cellcnt[`z',`x']/cellcnt[`z',`c']*100 } else { mat rowp[`z',`x'] = 0 } } } mat blankrow=J(1,1,-9) mat rownumber=newrow\blankrow if `vcnt'==1{ mat colper=colp mat rowper=rowp mat noper=cellcnt mat allrownumbers=rownumber if `do_N' mat Ncnt=Ncellcnt } else { mat colper=colper\colp mat rowper=rowper\rowp mat noper=noper\cellcnt mat allrownumbers=allrownumbers\rownumber if `do_N' mat Ncnt=Ncnt\Ncellcnt } } * combine data matrices with labels into display matrix if $dpanel ~= 1 { if `content'==1 mat full=allrownumbers,rowper else if `content'==2 mat full=allrownumbers,colper else if `content'== 3 mat full=allrownumbers,noper } else { mat fullcnt = allrownumbers,noper mat fullcol = allrownumbers,colper local ocols = colsof(fullcnt) local ncols = ((`ocols'-1)*2)+1 local nrows = rowsof(fullcnt) mat dcols = J(`nrows',`ncols',0) forval r = 1/`nrows' { mat dcols[`r',1] = fullcnt[`r',1] } local j = 2 local k = 2 forval c = 2/`ncols' { if mod(`c',2)==0 { forval r = 1/`nrows' { mat dcols[`r',`c'] = fullcnt[`r',`j'] } local j = `j'+1 } else { forval r = 1/`nrows' { mat dcols[`r',`c'] = fullcol[`r',`k'] } local k = `k'+1 } } mat full=dcols } } // if 2 or more variables } // if sstats == 0 * summary statistics tables if `sstats' == 1 { if `crtabs' == 0 { local vcnt=0 foreach v of local varlist{ local vcnt=`vcnt'+1 qui ta `v' if `touse', matrow(newrow) local valnames = "" local labelname : value label `v' local r = rowsof(newrow) local c = `stwidth' local l = `fstwidth' local m = `r'+1 mat vstats = J(`m',`l',0) forval z = 1/`m'{ if `z' < `m' { local valnum = newrow[`z',1] mat vstats[`z',1] = `valnum' } else mat vstats[`z',1] = -9 local f = 1 local q = 2 forval x = 2/`l'{ local statkind : word `f' of `cells' warnstats "`statkind'" if $nogood { * clearglobs // commented out b/c exit is not working?? exit } local statvar : word `q' of `cells' if `z' < `m' qui sum `statvar' [`weight' `exp'] if `touse' /// & `v' == `valnum' , detail else qui sum `statvar' [`weight' `exp'] if `touse' /// & !mi(`v'), detail if `dstats' == 1 { // change ratios here if require diff type if "`statkind'" == "iqr" local statres = r(p75)-r(p25) else if "`statkind'" == "r9010" local statres = r(p90)/r(p10) else if "`statkind'" == "r9050" local statres = r(p90)/r(p50) else if "`statkind'" == "r7525" local statres = r(p75)/r(p25) else if "`statkind'" == "r1050" local statres = r(p10)/r(p50) } else { if "`statkind'" == "median" local statkind "p50" if "`statkind'" == "count" local statkind "N" local statres = r(`statkind') } mat vstats[`z',`x'] = `statres' local f = `f' + 2 // increment by 2 so that leapfrog to next stat local q = `q' + 2 // increment by 2 so that leapfrog to next var } //end of loop across the cols } // end of loop down the rows if `vcnt' == 1 mat full = vstats else mat full = full\vstats } // end of foreach var } // end of crtabs == 0 else { local vcnt=0 qui ta `hvar' if `touse', matrow(hvar_row) foreach v of local vvar{ local vcnt=`vcnt'+1 qui ta `v' if `touse', matrow(vvar_row) local valnames = "" local labelname : value label `v' local r = rowsof(vvar_row) local c = rowsof(hvar_row) local l = `c' + 2 // need 1 extra column for labels and 1 for totals local m = `r'+1 mat vstats = J(`m',`l',0) forval z = 1/`m'{ if `z' < `m' { local vvalnum = vvar_row[`z',1] mat vstats[`z',1] = `vvalnum' } else mat vstats[`z',1] = -9 local f = 1 local statkind : word 1 of `cells' warnstats "`statkind'" if $nogood { * clearglobs // commented out b/c exit is not working?? exit } local statvar : word 2 of `cells' forval x = 2/`l'{ local hvalnum = hvar_row[`f',1] if `z' < `m' { if `x' < `l' qui sum `statvar' [`weight' `exp'] if `touse' /// & `v' == `vvalnum' & `hvar' == `hvalnum', detail else qui sum `statvar' [`weight' `exp'] if `touse' /// & `v' == `vvalnum' & !mi(`hvar'), detail } else { if `x' < `l' qui sum `statvar' [`weight' `exp'] if `touse' /// & !mi(`v') & `hvar' == `hvalnum', detail else qui sum `statvar' [`weight' `exp'] if `touse' /// & !mi(`v') & !mi(`hvar'), detail } if `dstats' == 1 { // change ratios here if require diff type if "`statkind'" == "iqr" local statres = r(p75)-r(p25) else if "`statkind'" == "r9010" local statres = r(p90)/r(p10) else if "`statkind'" == "r9050" local statres = r(p90)/r(p50) else if "`statkind'" == "r7525" local statres = r(p75)/r(p25) else if "`statkind'" == "r1050" local statres = r(p10)/r(p50) } else { if "`statkind'" == "median" local statkind "p50" if "`statkind'" == "count" local statkind "N" local statres = r(`statkind') } mat vstats[`z',`x'] = `statres' local f = `f' + 1 // work way across the hvars } //end of loop across the cols } // end of loop down the rows if `vcnt' == 1 mat full = vstats else mat full = full\vstats } // end of foreach var } // end of crtabs == 1 } // end of sstats == 1 * data collection complete - now assemble headers if `blankhead' == 0 { // if headers, continue, else jump straight to data if `single' == 1 { if `crtabs' == 0 local vlabel : variable label `varlist' else local vlabel : variable label `vvar' local leftlab = subinstr("`vlabel'"," ","_",.) } else local leftlab = "_" if `crtabs' == 0 { // begin one way tables local thecols "" if `sstats' == 0 { // begin freq tables local thecols "" if `fcnt' == 1 & `fper' == 1 & `fcum' == 1 /// local thecols "Number Per_cent Cum_Per_cent" if `fcnt' == 1 & `fper' == 0 & `fcum' == 0 /// local thecols "Number" if `fcnt' == 1 & `fper' == 1 & `fcum' == 0 /// local thecols "Number Per_cent" if `fcnt' == 1 & `fper' == 0 & `fcum' == 1 /// local thecols "Number Cum_Per_cent" if `fcnt' == 0 & `fper' == 1 & `fcum' == 1 /// local thecols "Per_cent Cum_Per_cent" if `fcnt' == 0 & `fper' == 1 & `fcum' == 0 /// local thecols "Per_cent" if `fcnt' == 0 & `fper' == 0 & `fcum' == 1 /// local thecols "Cum_Per_cent" } // if sstats == 0 else if `sstats' == 1 { // begin multiple stats across cols local numstatvars : word count `cells' local l = `numstatvars' local q = 2 forval x = 1/`l'{ local statvar : word `q' of `cells' if "`statvar'" ~= "" local svlab : variable label `statvar' local svlab = subinstr("`svlab'"," ","_",.) if `q' == 2 local thecols "`svlab'" else { if "`statvar'" ~= "" local thecols "`thecols' `svlab'" } local q = `q' + 2 } } // end sstats == 1 } // end crtabs == 0 else if `crtabs' == 1 { // begin two way tables local hlabel : variable label `hvar' local rightlab = subinstr("`hlabel'"," ","_",.) local thecols "" local xcols "" local k = colsof(hvals) local labelname: value label `hvar' local labelname = subinstr("`labelname'"," ","_",.) forval j = 1/`k' { local m = hvals[1,`j'] local valnm: label `labelname' `m' local valnm = subinstr("`valnm'"," ","_",.) local thecols "`thecols' `valnm'" } local totword = "`hword'" local totword = subinstr("`totword'"," ","_",.) local thecols "`thecols' `totword'" if `do_Nc' local thecols "`thecols' `Nlabel'" if $dpanel == 1 { // double panel two way tables local k = colsof(hvals) + 1 forval j = 1/`k' { local xcols "`xcols' Num %" } } // end dpanel == 1 } // end two way tables * check position of vertical var lab & assign contents to headers local head1 ="_" local head2 = "_" local head3 = "_" if "`leftlab'" == "" local leftlab "_" if "`lefthd'" ~= "" local head`lefthd' "`leftlab'" else { if $dpanel == 1 local head3 "`leftlab'" else local head2 "`leftlab'" } if `crtabs' == 1 { local head1 "`head1' `rightlab'" local head2 "`head2' `thecols'" } else local head2 "`head2' `thecols'" if $dpanel == 1 local head3 "`head3,' `xcols'" * replace individual lines with user headers where applicable forval j = 1/3 { local uh`j' = 0 // uh1 to uh3 meaning user headers if "`topstring`j''" ~= "" { local sub`j' "" local head`j' "" tokenize "`topstring`j''", parse("$dl") if "`1'" ~= "_" local sub`j' = subinstr("`1'"," ","_",.) else local sub`j' "_" local head`j' "`head`j'' `sub`j''" mac shift 2 while "`1'" ~= "" { local sub`j' = subinstr("`1'"," ","_",.) local head`j' "`head`j'' `sub`j''" mac shift 2 } local uh`j' = 1 } } } // end blankhead == 0 * DATA & HEADERS * send to screen (if chosen) and to tempfile tempname outfile tempfile tempfile file open `outfile' using "`tempfile'", write * values needed for correct screen display local lpos = `labw-1' local cpos = `labw'+1 local pos= `gap' local numcols = colsof(full)-1 file write `outfile' "`numcols'" _n if "`tabw'" ~= "" { local linewide = `tabw'-(`cpos'+1) } else { local linewide=c(linesize) -(`cpos'+1) } if `scr' di as text "{hline `cpos'}{c TT}{hline `linewide'}" * headers only if noheader not specified, hence blankhead == 0 if `blankhead' == 0 { forval j= 1/3 { local head`j'=ltrim("`head`j''") local head`j'=rtrim("`head`j''") if "`head`j''" ~= "_" | "`head`j''" ~= "_" { local numhcols: word count `head`j'' local str`j': word 1 of `head`j'' file write `outfile' "`str`j''" local str`j' = subinstr("`str`j''","_"," ",.) local str`j' = abbrev("`str`j''",`labw'-2) if `scr' di as text "{ralign `lpos': `str`j''}" _c if `scr' di as text "{col `cpos'} {c |}" _c local tpos = `cpos'+3 forval k = 2/`numhcols' { local str`j': word `k' of `head`j'' file write `outfile' "$dl`str`j''" local str`j' = subinstr("`str`j''","_"," ",.) if `uh`j'' ~= 1 & `j'> 1{ //only fiddle for defaults below line 1 local abbwide = `gap' if `j' == 2 & $dpanel == 1 local abbwide = `gap'*2 local str`j' = abbrev("`str`j''",`abbwide'-1) if `scr' di as text "{ralign `abbwide': `str`j''}" _c } else if `scr' di as text "{ralign `gap': `str`j''}" _c } if `scr' di file write `outfile' _n } } if `scr' di as text "{hline `cpos'}{c +}{hline `linewide'}" file write `outfile' "linehere" _n } // if blankhead == 0 * begin (if `scr') displaying data & writing to tempfile if `crtabs' == 0 { local r=rowsof(full)+1 local w=colsof(full) local p=1 while `p' < `r' { foreach v of local varlist{ local labelname: value label `v' local vname: variable label `v' if `single' == 0 { local v_name = subinstr("`vname'"," ","_",.) if "`glbtot'" == "`v'" { local skip 0 file write `outfile' "@@`v_name'" local vname = abbrev("`vname'",`labw'-2) if `scr' di as text "{ralign `labw': `vname'} {c |}" _c } else { local skip 1 file write `outfile' "`v_name'" _n local vname = abbrev("`vname'",`labw'-2) if `scr' di as text "{ralign `labw': `vname'} {c |}" } } local k=0 while `k' ~= -9{ local f=full[`p',1] local valnm: label `labelname' `f' local val_nm = subinstr("`valnm'"," ","_",.) if `skip' { file write `outfile' "`val_nm' $dl" local valnm = abbrev("`valnm'",`labw'-2) if `scr' di as text "{ralign `labw': `valnm'}" _c if `scr' di as text " {c |} " _c } else { file write `outfile' " $dl" } local j=`w'-1 local pos= `labw' + 5 local whichcol "" if `sstats' == 0 { local numfreq = 0 if `fcnt' ==1 { local whichcol = "`whichcol' 2" local numfreq = `numfreq'+1 } if `fper' ==1 { local whichcol = "`whichcol' 3" local numfreq = `numfreq'+1 } if `fcum' ==1 { local whichcol = "`whichcol' 4" local numfreq = `numfreq'+1 } local z = 1 tokenize "`whichcol'" forval x = 1/`numfreq' { if `numforms'==1 local form "`format'" else local form: word `z' of `format' if `scr' di as res "{col `pos'}" `form' (full[`p',`1']) _c file write `outfile' `form' (full[`p',`1']) if `x' < `numfreq' file write `outfile' "$dl" local pos = `pos' + `gap' local z = `z'+1 macro shift } if `scr' di file write `outfile' _n } else if `sstats' == 1 { local z = 1 forval x=2/`j'{ if `numforms'==1 local form "`format'" else local form: word `z' of `format' if `scr' di as res "{col `pos'}" `form' (full[`p',`x']) _c file write `outfile' `form' (full[`p',`x']) "$dl" local pos = `pos' + `gap' local z = `z'+1 } if `numforms'==1 local form "`format'" else local form: word `z' of `format' if `scr' di as res "{col `pos'}" `form' (full[`p',`w']) file write `outfile' `form' (full[`p',`w']) _n } // end if sstats == 1 local p=`p'+1 local k=full[`p',1] } local v_word = subinstr("`vword'"," ","_",.) if `single' == 1 { if `scr' di as text "{hline `cpos'}{c +}{hline `linewide'}" file write `outfile' "linehere" _n } if `dotot' file write `outfile' "`v_word' $dl" local totword = abbrev("`vword'",`labw'-2) if `scr' & `dotot' di as text "{ralign `labw': `totword'}" _c if `scr' & `dotot' di as text " {c |} " _c local pos= `labw' + 5 if `sstats' == 0 { local z = 1 tokenize "`whichcol'" forval x = 1/`numfreq' { if `numforms'==1 local form "`format'" else local form: word `z' of `format' if `scr' & `dotot' di as res "{col `pos'}" `form' (full[`p',`1']) _c if `dotot' file write `outfile' `form' (full[`p',`1']) if `x' < `numfreq' & `dotot' file write `outfile' "$dl" local pos = `pos' + `gap' local z = `z' +1 macro shift } if `scr' & `dotot' di if `dotot' file write `outfile' _n } else if `sstats' == 1{ local z = 1 forval x=2/`j'{ if `numforms'==1 local form "`format'" else local form: word `z' of `format' if `scr' & `dotot' di as res "{col `pos'}" `form' (full[`p',`x']) _c if `dotot' file write `outfile' `form' (full[`p',`x']) "$dl" local pos = `pos' + `gap' local z = `z'+1 } if `numforms'==1 local form "`format'" else local form: word `z' of `format' if `scr' & `dotot' di as res "{col `pos'}" `form' (full[`p',`w']) if `dotot' file write `outfile' `form' (full[`p',`w']) _n } // end if sstats == 1 local p=`p'+1 if `p'~=`r' { if `scr' di as text "{hline `cpos'}{c +}{hline `linewide'}" file write `outfile' "linehere" _n } } } if `scr' di as text "{hline `cpos'}{c BT}{hline `linewide'}" } // if crtabs == 0 else if `crtabs' == 1 { local r=rowsof(full)+1 local w=colsof(full) if `do_N' local numN = colsof(Ncnt) // needed if asking for N local p=1 while `p' < `r' { foreach v of local vvar{ local labelname: value label `v' local vname: variable label `v' if `single' == 0 { local v_name = subinstr("`vname'"," ","_",.) if "`glbtot'" == "`v'" { local skip 0 if `do_Nl' { file write `outfile' "@@`v_name'" file write `outfile' "_`Nlab1'" file write `outfile' `Nform' (Ncnt[`p',`numN']) file write `outfile' "`Nlab2'" } else file write `outfile' "@@`v_name'" local vname = abbrev("`vname'",`labw'-2) if `scr' di as text "{ralign `labw': `vname'} {c |}" _c } else { local skip 1 file write `outfile' "`v_name'" _n local vname = abbrev("`vname'",`labw'-2) if `scr' di as text "{ralign `labw': `vname'} {c |}" } } local k=0 while `k' ~= -9{ local f=full[`p',1] local valnm: label `labelname' `f' local val_nm = subinstr("`valnm'"," ","_",.) if `skip' { if `do_Nl' { file write `outfile' "`val_nm'" file write `outfile' "_`Nlab1'" file write `outfile' `Nform' (Ncnt[`p',`numN']) file write `outfile' "`Nlab2'" file write `outfile' " $dl" } else file write `outfile' "`val_nm' $dl" local valnm = abbrev("`valnm'",`labw'-2) if `scr' di as text "{ralign `labw': `valnm'}" _c if `scr' di as text " {c |} " _c } else { file write `outfile' " $dl" } local j=`w'-1 local pos= `labw' + 5 forval x=2/`j'{ formats `x' if `scr' di as res "{col `pos'}" $form (full[`p',`x']) _c file write `outfile' $form (full[`p',`x']) "$dl" local pos = `pos' + `gap' } formats `w' if `scr' di as res "{col `pos'}" $form (full[`p',`w']) _c file write `outfile' $form (full[`p',`w']) if `do_Nc' { local pos = `pos' + `gap' if `scr' di as res "{col `pos'}" `Nform' (Ncnt[`p',`numN']) _c file write `outfile' "$dl" `Nform' (Ncnt[`p',`numN']) } if `scr' di file write `outfile' _n local p=`p'+1 local k=full[`p',1] } local v_word = subinstr("`vword'"," ","_",.) if `single' == 1 { if `scr' di as text "{hline `cpos'}{c +}{hline `linewide'}" file write `outfile' "linehere" _n } if `dotot' & `do_Nl' { file write `outfile' "`v_word'" file write `outfile' "_`Nlab1'" file write `outfile' `Nform' (Ncnt[`p',`numN']) file write `outfile' "`Nlab2'" file write `outfile' " $dl" } else if `dotot' file write `outfile' "`v_word' $dl" local totword = abbrev("`vword'",`labw'-2) if `scr' & `dotot' di as text "{ralign `labw': `totword'}" _c if `scr' & `dotot' di as text " {c |} " _c local j=`w'-1 local pos= `labw' + 5 forval x=2/`j'{ formats `x' if `scr' & `dotot' di as res "{col `pos'}" $form (full[`p',`x']) _c if `dotot' file write `outfile' $form (full[`p',`x']) "$dl" local pos = `pos' + `gap' } formats `w' if `scr' & `dotot' di as res "{col `pos'}" $form (full[`p',`w']) _c if `dotot' file write `outfile' $form (full[`p',`w']) if `dotot' & `do_Nc' { local pos = `pos' + `gap' if `scr' di as res "{col `pos'}" `Nform' (Ncnt[`p',`numN']) _c file write `outfile' "$dl" `Nform' (Ncnt[`p',`numN']) } if `scr' & `dotot' di if `dotot' file write `outfile' _n local p=`p'+1 if `p'~=`r' { if `scr' di as text "{hline `cpos'}{c +}{hline `linewide'}" file write `outfile' "linehere" _n } } } if `scr' di as text "{hline `cpos'}{c BT}{hline `linewide'}" } // end crtabs == 1 if `dochi' == 1 & `scr' { di di as text "`chistr'" _n } file close `outfile' * file routines: process tempfile & send to user file * adding additions before & after & applying style tempname mainfile capture file open `mainfile' using "`using'", write `opt' if _rc==602 { di di as err "File `using' already exists." di as err "Use the replace option to overwrite", di as err "or choose another filename." di clearglobs exit } capture file write `mainfile' "" if _rc==111 { di di as err "File `using'" di as err "is already open inside another application." di as err "Please close it before running tabout." di clearglobs exit } * note that prefile (topf) is generic, not specific to any one style if "`prefile'" ~= "" { tempname topfile capture file open `topfile' using "`prefile'", read if _rc==601 { di di as err "File `prefile' not found." di as err "Check and retype file specification." di clearglobs exit } file read `topfile' line if `dotop' == 1 tokenize "`topinsert'", parse("$dl") while r(eof) == 0 { if `dotop' == 1 { if index("`line'","$ps") > 0 { local line : subinstr local line "$ps" "`1'" mac shift 2 } } file write `mainfile' `"`macval(line)'"' _n file read `topfile' line } file close `topfile' } * open the temp file with all the existing output file open `outfile' using "`tempfile'", read * tex output if `out' == 1 { if `bcode' == 1 { file write `mainfile' "\\documentclass{article}" _n file write `mainfile' "\\usepackage{multicol}" _n file write `mainfile' "\\begin{document}" _n local numcols = colsof(full)-1 local cstr = "l" forval x = 1/`numcols' { local cstr = "`cstr'"+"r" } file write `mainfile' "\\begin{tabular}{`cstr'}" _n file write `mainfile' "\\hline" _n } * main output starts here, headers first, then data file read `outfile' line // to grab number of cols local span = `line' if `do_Nc' local span = `span' + 1 if `blankhead' == 0 { file read `outfile' line local line : subinstr local line " " "", all local term = "\\\" forval j = 1/3 { if "`line'" ~= "linehere" { if `uh`j'' ~= 1 { local fletter = substr("`line'",1,1) if "`fletter'" ~= "_" { local fword = substr("`line'",1,index("`line'","$dl")-1) texclean "`fword'" dofont "$clnword" `tfont' "tex" file write `mainfile' " $fonted " local line : subinstr local line "`fword'" "_" } if `j' == 1 { tokenize "`line'", parse("$dl") mac shift 2 while "`1'" ~= "" { texclean "`1'" dofont "$clnword" `tfont' "tex" if `crtabs' == 1 { file write `mainfile' " & \\multicolumn{`span'}{c}{$fonted} \\\" _n } else file write `mainfile' " & $fonted" mac shift 2 } if `crtabs' == 0 file write `mainfile' " \\\\\" _n } // end first line if `j' == 2 { if $dpanel == 1{ tokenize "`line'", parse("$dl") mac shift 2 while "`1'" ~= "" { texclean "`1'" file write `mainfile' " & \\multicolumn{2}{c}{$clnword}" _n mac shift 2 } file write `mainfile' " \\\" _n } // end dpanel else { // not dpanel texclean "`line'" global clnword : subinstr global clnword "$dl" " & ", all file write `mainfile' "$clnword \\\" _n } } if `j' == 3 { texclean "`line'" global clnword : subinstr global clnword "$dl" " & ", all file write `mainfile' "$clnword \\\" _n } } // end default else userlines "`line'" `mainfile' "tex" file read `outfile' line local line : subinstr local line " " "", all } // end line condition } // end forval loops texline `lspace' `mainfile' `rule' } // end blankhead * header done, now data file read `outfile' line local line : subinstr local line " " "", all local lnum 1 while r(eof) == 0 { if "`line'" ~= "linehere" { if `lnum' == 1 & `single' ~= 1 { local totsym = substr("`line'",1,2) if "`totsym'" ~= "@@" { texclean "`line'" dofont "$clnword" `tfont' "tex" file write `mainfile' "$fonted \\\" _n } else { tokenize "`line'", parse("$dl") local llen=length("`1'") local shtline = substr("`1'",3,`llen'-2) texclean "`shtline'" dofont "$clnword" `tfont' "tex" file write `mainfile' "$fonted" mac shift 2 while "`1'" ~= "" { file write `mainfile' " & `1'" mac shift 2 } file write `mainfile' " \\\" _n } } else { tokenize "`line'", parse("$dl") texclean "`1'" file write `mainfile' "$clnword" mac shift 2 while "`1'" ~= "" { file write `mainfile' " & `1'" mac shift 2 } file write `mainfile' " \\\" _n } } // end not line else { texline `lspace' `mainfile' `rule' local lnum 0 } file read `outfile' line local line : subinstr local line " " "", all local lnum = `lnum'+1 } // end while not eof if `dochi' == 1 { texline `lspace' `mainfile' `rule' local fspan = `span'+1 file write `mainfile' "\\multicolumn{`fspan'}{@{}l}{`chistr'} \\\" _n } if `bcode' == 1 { file write `mainfile' "\\hline" _n file write `mainfile' "\\end{tabular}" _n file write `mainfile' "\\end{document}" _n } } // end tex output * html output if `out' == 2 { if `bcode' == 1 { file write `mainfile' "" _n file write `mainfile' "" _n file write `mainfile' "" _n } file read `outfile' line // to grab number of cols local span = `line' if `blankhead' == 0 { local fstime "" //this is needed the first time thru file read `outfile' line local line : subinstr local line " " "", all forval j = 1/3 { if "`line'" ~= "linehere" { if `uh`j'' ~= 1 { local fletter = substr("`line'",1,1) if "`fletter'" ~= "_" { local line : subinstr local line "_" " ", all local fword = substr("`line'",1,index("`line'","$dl")-1) dofont "`fword'" `tfont' "html" file write `mainfile' "$fonted" local line : subinstr local line "`fword'" "_" } if `j' == 1 { tokenize "`line'", parse("$dl") mac shift 2 while "`1'" ~= "" { local term = subinstr("`1'","_"," ",.) dofont "`term'" `tfont' "html" if `crtabs' == 1 { file write `mainfile' /// "$fonted" _n file write `mainfile' "" } else { if `single'==0 { file write `mainfile' "`fstime'$fonted" local fstime "" } else file write `mainfile' "$fonted" } mac shift 2 } if `crtabs' == 0 { file write `mainfile' _n file write `mainfile' "" } } // end first line if `j' == 2 { if $dpanel == 1{ tokenize "`line'", parse("$dl") mac shift 2 while "`1'" ~= "" { local term = subinstr("`1'","_"," ",.) file write `mainfile' /// " `term'" mac shift 2 } file write `mainfile' _n file write `mainfile' "" } // end dpanel else { // not dpanel local term : subinstr local line "_" " ", all local term : subinstr local term "$dl" "", all file write `mainfile' "`term'" _n file write `mainfile' "" } } if `j' == 3 { local line : subinstr local line "_" " ", all local term : subinstr local term "$dl" "", all file write `mainfile' "`term'" _n file write `mainfile' "" } } // end default else userlines "`line'" `mainfile' "html" file read `outfile' line local line : subinstr local line " " "", all } // end line condition } // end forval loops } // end blankhead * header done, now data file read `outfile' line local line : subinstr local line " " "", all local lnum 1 while r(eof) == 0 { if "`line'" ~= "linehere" { if `lnum' == 1 & `single' ~= 1 { local term : subinstr local line "_" " ", all dofont "`term'" `tfont' "html" file write `mainfile' "$fonted" _n file write `mainfile' "" } else { local term : subinstr local line "_" " ", all tokenize "`term'", parse("$dl") file write `mainfile' "`1'" mac shift 2 while "`1'" ~= "" { file write `mainfile' "`1'" mac shift 2 } file write `mainfile' _n file write `mainfile' "" } } // end not line else { local lnum 0 } file read `outfile' line local line : subinstr local line " " "", all local lnum = `lnum'+1 } // end while not eof if `dochi' == 1 { local fspan = `span'+1 file write `mainfile' "`chistr'" _n } if `bcode' == 1 { file write `mainfile' "" _n file write `mainfile' "" _n file write `mainfile' "" _n } } // end html output * tab delimitted output if `out' == 3 { file read `outfile' line // just to snuffle the number file write `mainfile' _n file read `outfile' line local line : subinstr local line " " "", all while r(eof) == 0 { if "`line'" ~= "linehere" { tokenize "`line'", parse("$dl") while "`1'" ~= "" { local outword = subinstr("`1'","_"," ",.) file write `mainfile' "`outword'" _tab mac shift 2 } file write `mainfile' _n } else { if `lspace'== 3 file write `mainfile' _n } file read `outfile' line local line : subinstr local line " " "", all } // end while not eof file write `mainfile' _n if `dochi' == 1 file write `mainfile' "`chistr'" _n } // end tab output * note that postfile (botf) is generic, not specific to any one style if "`postfile'" ~= "" { tempname botfile capture file open `botfile' using "`postfile'", read if _rc==601 { di di as err "File `postfile' not found." di as err "Check and retype file specification." di clearglobs exit } file read `botfile' line if `dobot' == 1 tokenize "`botinsert'", parse("$dl") while r(eof) == 0 { if `dobot' == 1 { if index("`line'","$ps") > 0 { local line : subinstr local line "$ps" "`1'" mac shift 2 } } file write `mainfile' `"`macval(line)'"' _n file read `botfile' line } file close `botfile' } file close `mainfile' di di as text "File written to: `using'" di if `cod' == 1 type "`using'" * tidy up and exit file close _all clearglobs end * to check on correct stats term * note the split lines for Intercooled Stata program warnstats args inword if index("N mean var sd skewness kurtosis sum min max","`inword'") == 0 & /// index("p1 p5 p10 p25 p50 p75 p90 p95 p99","`inword'") == 0 & /// index("count median iqr r9010 r9050 r7525 r1050","`inword'") == 0 { di as err "One of the statistics terms you entered in the cells option is incorrect" global nogood 1 } end * to simplify processing of double tables program formats args i if $dpanel == 1 { if mod(`i',2)==0 { global form = "$form1" } else { global form = "$form2" } } end program texline args kind texfile prnline if `kind' == 1 { file write `texfile' "`prnline'" _n } else if `kind' == 2 { file write `texfile' "`prnline'" _n file write `texfile' "`prnline'" _n } else if `kind' == 3 { file write `texfile' _n } else if `kind' == 0 { file write `texfile' "" } end program dofont args titlewd ftype ostyle if "`ostyle'" == "tex" { if "`ftype'" == "bold" global fonted "\\textbf{`titlewd'}" else if "`ftype'" == "italic" global fonted "\\emph{`titlewd'}" else if "`ftype'" == "plain" global fonted "`titlewd'" } else if "`ostyle'" == "html" { if "`ftype'" == "bold" global fonted "`titlewd'" else if "`ftype'" == "italic" global fonted "`titlewd'" else if "`ftype'" == "plain" global fonted "`titlewd'" } end * parses and cleans user headers, then outputs them program userlines args inline filenm ostyle if "`ostyle'" == "tex" { local inline : subinstr local inline "$dl" " & ", all local inline : subinstr local inline "_" " ", all file write `filenm' "`inline' \\\" _n } else if "`ostyle'" == "html" { local inline : subinstr local inline "$dl" "", all local inline : subinstr local inline "_" " ", all file write `filenm' "`inline'" _n } end program texclean args inword global clnword : subinstr local inword "_" " ", all global clnword : subinstr global clnword "%" " \\%", all global clnword : subinstr global clnword "&" " \\&", all end program clearglobs set linesize $oldsize macro drop form macro drop dpanel macro drop form1 macro drop form2 macro drop clnword macro drop fonted macro drop ps macro drop dl macro drop oldsize capture mat drop labs capture mat drop hvals capture mat drop newmat capture mat drop newrow capture mat drop newcol capture mat drop counts capture mat drop percents capture mat drop rownumber capture mat drop colnumber capture mat drop rowtot capture mat drop coltot capture mat drop wider capture mat drop longer capture mat drop blankrow capture mat drop allrownumbers capture mat drop full capture mat drop cellcnt capture mat drop colp capture mat drop colper capture mat drop rowper capture mat drop rowp capture mat drop noper capture mat drop fullcnt capture mat drop fullcol capture mat drop dcols capture mat drop cums capture mat drop freq capture mat drop vstats end