*! Cross-tabulation of 2 variables with display of percentages *! version 1.01 2002-08-28 *! Philip Ryan, University of Adelaide, South Australia program def tab2way, sortpreserve byable(recall) version 7 #delimit ; syntax varlist (min=2 max=2) [if] [in] [fw /] [ , noFREQ CELLPct ROWPct COLPct ALLPct ROWTot COLTot ALLTot Format(string) usemiss *] ; tempvar touse tempfwt v1 v2 freqcy rp strfreq cp lp; tempname origN; tempfile basal extrar extrac extrarc extral; mark `touse' `if' `in'; if "`usemiss'" == "" {; markout `touse' `varlist', strok; }; ***********************************; * gotta specify something ; ***********************************; if "`freq'" == "nofreq" & "`rowpct'" == "" & "`colpct'" == "" & "`cellpct'" == "" & "`allpct'" == "" {; di as error "no cell content specified"; #delimit cr exit } ***********************************; #delimit cr preserve /* orig data */ *********************************** * look after frequency weights *********************************** qui { if "`weight'" =="fweight" { gen double `tempfwt' = `exp' drop if `tempfwt' < 1|`tempfwt' ==. expand `tempfwt' local wflag 1 } } *********************************** *********************************** * keep original obs count *********************************** qui count if `touse' scalar def `origN' = r(N) *********************************** ********************************** * deals with tricky syntax problems at options boundary ********************************** tokenize `varlist' ********************************** *********************************** * change string vars to numeric for easier addition of missing/total categs *********************************** qui { forvalues i = 1/2 { local typev`i': type ``i'' if substr("`typev`i''",1,3) == "str" { encode ``i'', gen(`v`i'') local xlabel: variable label ``i'' if "`xlabel'" == "" { lab var `v`i'' "``i''" } } else { gen long `v`i'' = ``i'' local varlab: var label ``i'' if "`varlab'" == "" { lab var `v`i'' "``i'' } else { label var `v`i'' "`varlab'" } local vallab: value label ``i'' lab val `v`i'' `vallab' } sum `v`i'' local max`i' = r(max) } /* end -for- */ } /* end qui */ *********************************** *********************************** * specify values for new categories for missing and totals *********************************** local max12 = 2 + max(`max1', `max2') local missval = `max12'-1 if "`usemiss'" != "" { qui mvencode `v1' `v2', mv(`missval') } *********************************** *********************************** * specify display format for percents *********************************** if "`format'" == "" { local format "%8.2f" } else if substr("`format'", 1,1) != "%" { di as error "invalid format specified - first character must be " as input "%" exit } *********************************** *********************************** * set macros as flags for desired percents *********************************** if "`allpct'" != "" { local rowpct 1 local colpct 1 local cellpct 1 } else { if "`rowpct'" != "" { local rowpct 1 } if "`colpct'" != "" { local colpct 1 } if "`cellpct'" != "" { local cellpct 1 } } *********************************** qui save "`basal'" local anytot = "`rowtot'" !=""|"`coltot'"!=""|"`celltot'"!=""|"`alltot'"!="" *********************************** * calculate totals and save data to temp files *********************************** if `anytot' { ****** begin row total qui { collapse (count) `v2' if `touse' , by(`v1') expand `v2' replace `v2' = `max12' save "`extrar'" } ****** end of row total qui use "`basal'", clear ****** begin col total qui { collapse (count) `v1' if `touse' , by(`v2') expand `v1' replace `v1' = `max12' save "`extrac'" } ****** end of col total qui use "`basal'", clear ****** begin row/col total qui { collapse (count) `v1' `v2' if `touse' expand `v1' replace `v1' = `max12' replace `v2' = `max12' save "`extrarc'" } ****** end of row/col total } /* end if anytot */ *********************************** qui use "`basal'", clear *********************************** * augment data set with totals if specified *********************************** if `anytot' { qui { if "`rowtot'" != "" | "`alltot'" != "" { local rt 1 append using "`extrar'" } if "`coltot'" != "" | "`alltot'" != "" { local ct 1 append using "`extrac'" } if ("`rowtot'" != "" & "`coltot'" != "") | "`alltot'" != "" { local rct 1 append using "`extrarc'" } } /* end qui */ } /* end if anytot */ *********************************** *********************************** * labels *********************************** local rowlab: value label `v2' local collab: value label `v1' if "`rowlab'" == "" { lab def `v2' `missval' "missing", modify lab val `v2' `v2' } else { lab def `rowlab' `missval' "missing", modify } if "`collab'" == "" { lab def `v1' `missval' "missing", modify lab val `v1' `v1' } else { lab def `collab' `missval' "missing", modify } if `anytot' { if "`rt'" == "1" { if "`rowlab'" == "" { lab def `v2' `max12' "TOTAL", modify lab val `v2' `v2' } else { lab def `rowlab' `max12' "TOTAL", modify } } if "`ct'" == "1" { if "`collab'" == "" { lab def `v1' `max12' "TOTAL", modify lab val `v1' `v1' } else { lab def `collab' `missval' "missing" `max12' "TOTAL", modify } } } /* end anytot */ *********************************** *********************************** * calculate percentages *********************************** bysort `touse' `v1' `v2' : gen long `freqcy' = _N bysort `touse' : gen long `lp' = `origN' qui replace `lp' = 100 * `freqcy' / `lp' bysort `touse' `v1' : gen long `rp' = _N qui replace `rp' = 100 * `freqcy' / `rp' if "`rt'" == "1" { qui replace `rp' = 2* `rp' if `v1' == `max12' } bysort `touse' `v2' : gen long `cp' = _N qui replace `cp' = 100 * `freqcy' / `cp' if "`ct'" == "1" { qui replace `cp' = 2*`cp' if `v2' == `max12' } *********************************** *********************************** * change counts to strings for display *********************************** qui { if "`freq'" != "nofreq" { gen str1 `strfreq' = "" replace `strfreq' = string(`freqcy') local freqyes " cell frequencies and" } else { local strfreq "" } } *********************************** *********************************** * use -tabdisp- to display table *********************************** di _new if "`wflag'" != "" { display as text "Frequency weights are based on the expression: " as res "`exp'" } if "`rowpct'" == "1" & "`colpct'" == "1" & "`cellpct'" == "1" { display as text "Table entries are`freqyes' cell, row and column percentages" if "`usemiss'" =="" {di as text "Missing categories ignored"} tabdisp `v1' `v2' if `touse', c(`strfreq' `lp' `rp' `cp' ) /* */ format(`format') `options' } else if "`rowpct'" == "1" & "`cellpct'" == "1" { display as text "Table entries are`freqyes' cell percentages and row percentages" if "`usemiss'" =="" {di as text "Missing categories ignored"} tabdisp `v1' `v2' if `touse', c(`strfreq' `lp' `rp') /* */ format(`format') `options' } else if "`colpct'" == "1" & "`cellpct'" == "1" { display as text "Table entries are`freqyes' cell percentages and column percentages" if "`usemiss'" =="" {di as text "Missing categories ignored"} tabdisp `v1' `v2' if `touse', c(`strfreq' `lp' `cp') /* */ format(`format') `options' } else if "`rowpct'" == "1" & "`colpct'" == "1" { display as text "Table entries are`freqyes' row percentages and column percentages" if "`usemiss'" =="" {di as text "Missing categories ignored"} tabdisp `v1' `v2' if `touse', c(`strfreq' `rp' `cp') /* */ format(`format') `options' } else if "`rowpct'" == "1" { display as text "Table entries are`freqyes' row percentages" if "`usemiss'" =="" {di as text "Missing categories ignored"} tabdisp `v1' `v2' if `touse', c(`strfreq' `rp' ) /* */ format(`format') `options' } else if "`colpct'" == "1" { display as text "Table entries are`freqyes' column percentages" if "`usemiss'" =="" {di as text "Missing categories ignored"} tabdisp `v1' `v2' if `touse', c(`strfreq' `cp' ) /* */ format(`format') `options' } else if "`cellpct'" == "1" { display as text "Table entries are`freqyes' cell percentages" if "`usemiss'" =="" {di as text "Missing categories ignored"} tabdisp `v1' `v2' if `touse', c(`strfreq' `lp' ) /* */ format(`format') `options' } else { display as text "Table entries are cell frequencies" if "`usemiss'" =="" {di as text "Missing categories ignored"} tabdisp `v1' `v2' if `touse', c(`strfreq') /* */ format(`format') `options' } restore end