*! 1.1.0 NJC 25 Feb 2007 *! 1.0.0 NJC 10 May 2006 program shorth, sortpreserve rclass byable(recall) version 8.2 syntax varlist(numeric) [if] [in] /// [, INSIDE(str) Name(int 32) Proportion(numlist >0 <1 max=1) Spaces(int 2) /// Format(str) BY(varname) Generate(str) GRaph Ties ALLobs MISSing ] quietly { // what observations to use if "`allobs'" != "" marksample touse, novarlist else marksample touse if "`by'" != "" & "`missing'" == "" markout `touse' `by', strok count if `touse' if r(N) == 0 error 2000 // variable(s) or group(s) local nv : word count `varlist' // generate() option if "`generate'" != "" { if `nv' > 1 { di as err /// "generate() cannot be combined with `nv' variables" exit 198 } if _by() { di as err /// "generate() cannot be combined with by: : use by() option" exit 198 } local OK length max LMS min shorth foreach g of local generate { local eq = index("`g'", "=") if `eq' == 0 { di as err "generate(): invalid syntax" exit 198 } local g1 = substr("`g'", 1, `eq' - 1) confirm new variable `g1' local G1 `G1' `g1' local g2 = substr("`g'", `eq' + 1, .) if "`g2'" == "lms" local g2 "LMS" if !`: list g2 in OK' { di as err "generate(): `g2' invalid" exit 198 } local G2 `G2' `g2' } foreach g1 of local G1 { generate double `g1' = . } } // by option if "`by'" != "" { if `nv' > 1 { di as err /// "by() cannot be combined with `nv' variables" exit 198 } tempname stub separate `varlist' if `touse', /// by(`by') g(`stub') veryshortlabel `missing' local varlist "`r(varlist)'" } // inside() option if "`inside'" != "" { confirm new var `inside' if `nv' > 1 { di as err /// "inside() cannot be combined with `nv' variables" exit 198 } gen byte `inside' = 0 } if "`by'`allobs'" == "" { noi di _n as txt "(n = " as res r(N) as txt ")" } // display preparation and initiation local nam = 0 foreach v of local varlist { if "`by'" != "" { local nam = max(`nam', length(`"`: variable label `v''"')) } else local nam = max(`nam', length("`v'")) } local col = min(`name', `nam') + 1 if "`format'" == "" local format "%8.2g" local ndigits : subinstr local format "%" "" local ndigits : subinstr local ndigits "0" "" local ndigits : subinstr local ndigits "-" "" local ndigits = substr("`ndigits'", 1, 1) if "`ndigits'" == "d" { local ndigits = 9 local ldigits = 6 local lfmt "%6.0f" } else if `ndigits' < 6 { local fmt "`format'" local format : subinstr local format "`ndigits'" "6" noi di as txt "(note: format `fmt' changed to `format')" local ndigits = 6 } if "`ldigits'" == "" local ldigits = `ndigits' if "`lfmt'" == "" local lfmt "`format'" local sp "{space `spaces'}" local SP : di _dup(`spaces') " " if "`by'`allobs'" != "" local N : di %6s "n`SP'" local S : di %`ndigits's "shorth" local I : di %`ndigits's "min" local M : di %`ndigits's "LMS" local X : di %`ndigits's "max" local L : di %`ldigits's "length" noi di _n as txt /// "{col `col'}`sp'`N'`S'`sp'`I'`sp'`M'`sp'`X'`sp'`L'" local line = `col' - 1 + 5 * `spaces' + length("`N'`S'`I'`M'`X'`L'") noi di "{hline `line'}" local footnote = 0 local tiesnote = 0 // initialisation of calculation if "`proportion'" == "" local proportion = 0.5 local what = cond(`proportion' != 0.5, "fraction", "half") local whats = cond(`proportion' != 0.5, "fractions", "halves") replace `touse' = -`touse' tempvar work i gen double `work' = . gen long `i' = . // loop over variables (-separate- results if -by()-) foreach v of local varlist { local which = cond("`by'" != "", `"`: variable label `v''"', "`v'") bysort `touse' (`v') : replace `i' = _n count if `touse' & `v' < . local n = r(N) local n2 = floor(`proportion' * r(N)) local n1 = `n' - `n2' replace `work' = /// cond(inrange(_n, 1, `n1'), `v'[_n + `n2'] - `v', .) // check for tied shortest half sort `work' `i' count if `work' == `work'[1] if r(N) > 1 { local footnote = 1 local flag " (*)" local l = `i'[ceil(r(N) / 2)] if "`ties'" != "" { local ++tiesnote if c(version) >= 9 { levelsof `i' in 1/`r(N)', local(levels) } else levels `i' in 1/`r(N)', local(levels) local tie`tiesnote' `levels' local tiesvar `tiesvar' `v' } } else { local flag local l = `i'[1] } if "`graph'" != "" { noi scatter `work' `i' in 1/`n1', /// ytitle(shortest `what') /// xtitle(index) subtitle(`"`which'"') more } local m = `l' + `n2' sort `touse' `i' su `v' in `l'/`m', meanonly if "`inside'" != "" { replace `inside' = 1 in `l'/`m' } * set trace on if "`by'`allobs'" != "" local nshow : di %6s "`n'`SP'" noi di as text `"`which'{col `col'}"' "`sp'" /// as res "`nshow'" /// as res `format' r(mean) "`sp'" /// as res `format' r(min) "`sp'" /// as res `format' (r(min) + r(max)) / 2 "`sp'" /// as res `format' r(max) "`sp'" /// as res `lfmt' r(max) - r(min) "`sp'" /// as txt "`flag'" * set trace off // generate? local j = 1 foreach g1 of local G1 { local g2 : word `j++' of `G2' if "`g2'" == "length" { replace `g1' = r(max) - r(min) if `touse' & `v' < . } else if "`g2'" == "max" { replace `g1' = r(max) if `touse' & `v' < . } else if "`g2'" == "LMS" { replace `g1' = (r(max) + r(min)) / 2 if `touse' & `v' < . } else if "`g2'" == "min" { replace `g1' = r(min) if `touse' & `v' < . } else if "`g2'" == "shorth" { replace `g1' = r(mean) if `touse' & `v' < . } } // leaves only last-calculated in memory return scalar length = r(max) - r(min) return scalar rank_max = `m' return scalar max = r(max) return scalar LMS = (r(min) + r(max)) / 2 return scalar rank_min = `l' return scalar min = r(min) return scalar shorth = r(mean) return scalar N = `n' } } // endnotes if `footnote' di _n as txt "(*) shortest `what' not unique" if `tiesnote' { di _n "Ties for `whats' starting at ranks " local i = 1 foreach v of local tiesvar { if "`by'" != "" local v : variable label `v' di as txt `"`v'"' as res "{col `col'}`sp'`tie`i++''" } } end