program def taba
*! 1.0.0 NJC 15 February 1999
        version 5.0
        local varlist "ex"
        local if "opt"
        local in "opt"
        local weight "fweight noprefix"
        parse "`*'"
        parse "`varlist'", parse(" ")

        if "`exp'" == "" {
                tempvar exp
                gen byte `exp' = 1
        }

        tempvar touse n pc miss sn
        mark `touse' `if' `in'
        local len3 = 29

        while "`1'" != "" {
                capture confirm string variable `1'
                local isstr = _rc == 0
                if `isstr' {
                        tempvar strcopy
                        local type : type `1'
                        qui gen `type' `strcopy'  = trim(`1')
                        qui compress `strcopy'
                        local type : type `strcopy'
                        drop `strcopy'
                        local len = substr("`type'",4,.)
                        local len1 = cond(`len' <= 9, 4, `len' - 5)
                        local len1 = min(`len1', 35)
                        local len2 = cond(`len' <= 9, 10, 1 + `len')
                        local len2 = min(`len2', 41)
                }
                else {
                        local len1 = 4
                        local len2 = 10
                }

                qui {
                        if `isstr' { gen byte `miss' = `1' == "" }
                        else gen byte `miss' = `1' == .

                        sort `touse' `1'
                        by `touse' `1' : /*
                         */ gen long `n' = sum(`exp') if `touse'
                        by `touse' `1' : replace `n' = `n'[_N]

                        su `exp' if `touse' & !`miss', meanonly
                        local npres = _result(18)
                        gen `pc' = `n' * 100 / `npres'

                        su `exp' if `touse' & `miss', meanonly
                        local nmiss = _result(18)
                        su `exp' if `touse', meanonly
                        local nall = _result(18)
                        replace `pc' = /*
                        */ `nmiss' * 100 / `nall' if `miss' & `touse'

                        gen str1 `sn' = ""
                        replace `sn' = string(`n')
                }

                label var `sn' "Freq."
                label var `pc' " % of present"
                tabdisp `1' if `touse' & !`miss', c(`sn' `pc') f(%9.2f)
                di in g _dup(`len1') " " "Total |" in y %14.0f `npres'
                di in g _dup(`len2') "-" "+" _dup(`len3') "-"
                if `nmiss' {
                        local len1 = 4
                        local len2 = 10
                        label var `pc' "% of all obs."
                        tabdisp `1' if `touse' & `miss', /*
                        */ c(`sn' `pc') f(%9.2f)
                        di in g _dup(`len1') " " "Total |" in y %14.0f `nall'
                        di in g _dup(`len2') "-" "+" _dup(`len3') "-"
                }

                drop `n' `pc' `miss' `sn'
                mac shift
        }
end