program define tabsort *! NJC 1.1.0 27 July 1998 version 5.0 local varlist "req max(2)" local if "opt" local in "opt" local weight "fweight aweight iweight" local options "Missing noRSort noCSort noLAbel Generate(str)" local options "`options' Summari(str) SOrt(str) REVerse *" parse "`*'" parse "`varlist'", parse(" ") local so = substr("`sort'",1,1) if "`sort'" == "" | "`so'" == "f" | "`so'" == "c" { local sort "freq" local so "f" } if "`summari'" != "" { unabbrev `summari', max(1) local summari "$S_1" if "`sort'" != "freq" { if "`so'" == "m" { local sort "mean" } else if "`so'" == "s" { local sort "sd" } else { di in r "sort( ) should be freq, mean or sd" exit 198 } } local summ "s(`summari')" } else { if "`so'" != "f" { di in r "sort(`sort') not allowed without summarize( )" exit 198 } } tempvar touse w W stat group1 group2 mark `touse' `if' `in' if "`missing'" == "" { markout `touse' `varlist', strok } qui { if "`exp'" == "" { gen `w' = 1 } else { /* do this now, just in case expression depends on _n */ gen `w' `exp' markout `touse' `w' local exp "= `w'" } gen `W' = . gen double `stat' = . } * sort on row stats, or carry row variable as is if "`rsort'" == "" { local slist "`1'" } else local tlist "`1'" * sort on col stats, or carry col variable as is if "`csort'" == "" { local slist "`slist' `2'" } else local ulist "`2'" local nsort : word count `slist' local k = 1 qui while `k' <= `nsort' { local var`k' : word `k' of `slist' local type : type `var`k'' local numvar = substr("`type'",1,3) != "str" local fmt : format `var`k'' local vallab : value label `var`k'' sort `touse' `var`k'' if "`sort'" == "freq" { by `touse' `var`k'' : replace `stat' = sum(`w') if `touse' by `touse' `var`k'' : replace `stat' = `stat'[_N] } else { /* mean or sd */ by `touse' `var`k'' : replace `W' = sum(`w') / sum(1) /* */ if `touse' by `touse' `var`k'' : replace `W' = `w' / `W'[_N] by `touse' `var`k'' : replace `stat' = /* */ sum(`W' * `summari') / sum(1) if `touse' by `touse' `var`k'' : replace `stat' = `stat'[_N] } if "`sort'" == "sd" { by `touse' `var`k'' : replace `stat' = /* */ sqrt(sum(`W' * (`summari' - `stat')^2) / (sum(1) - 1)) by `touse' `var`k'' : replace `stat' = `stat'[_N] } if "`reverse'" == "" { replace `stat' = -`stat' } sort `stat' `var`k'' by `stat' `var`k'' : gen int `group`k'' = _n == 1 if `touse' replace `group`k'' = sum(`group`k'') local ng = `group`k''[_N] local i = 1 local j = 1 while `i' <= `ng' { local lbl = `var`k''[`j'] if `numvar' { local big = `lbl' >= 1e8 | `lbl' <= -1e7 local small = `lbl' < 1 & `lbl' > 0 local small = `small' | (`lbl' > -1 & `lbl' < 0) local nonint = `lbl' != int(`lbl') if `big' | `small' { local lbl : di %7.0e `lbl' } else if `nonint' { local lbl : di `fmt' `lbl' } if "`vallab'" != "" { local lbl : label `vallab' `lbl' } } else { /* see notes at end */ if "`lbl'" == "" { local len = length(`var`k''[`j']) if `len' == 0 { local lbl "missing" } else local lbl : di "|" _dup(`len') " " "|" } } label define `group`k'' `i' "`lbl'", add count if `group`k'' == `i' local j = `j' + _result(1) local i = `i' + 1 } label val `group`k'' `group`k'' _crcslbl `group`k'' `var`k'' local tlist "`tlist' `group`k''" local k = `k' + 1 } tabulate `tlist' `ulist' [`weight' `exp'] if `touse', /* */ `summ' `label' `options' if "`label'" == "nolabel" & "`slist'" != "" { local slist = trim("`slist'") if `nsort' == 2 { local s "s" } di in bl /* */ "Note: labels of `slist' are not those of original variable`s'" } if "`generat'" != "" { qui tab `varlist', gen(`generat') } capture label drop `group1' capture label drop `group2' end /* Spaces in string values: get lost in copying -- local lbl = `var`k''[`j'] must put them back again! Missing string values: label def "", add -- will not work label def " ", add -- would work, but then missings and blanks would give the same result */