*! mcompr1.ado (sg28: STB-22) program define mcompr1 version 3.1 local options "GENerate(string) Cutoff(real .05) ID(string) Default(string) LAbel" local varlist "req ex max(1)" parse "`*'" parse "`varlist'", parse(" ") if "`default'"=="" { local default default } local numcat = $S_2 + ("$S_4"!="nocons") tempvar bb vv ll vv2 qui gen `bb' = . if "`id'"=="" { tempname id } qui gen str28 `id' = "" local i 1 local ii 1 if ("$S_4"!="nocons") { qui replace `bb' = 0 in 1 if "`id'"!="" { qui replace `id' = "`default'" in 1 } local i 2 } while `i' <= `numcat' { local nam : word `ii' of $S_3 qui replace `bb' = _b[`nam'] in `i' if ("`label'"!="") { local nam : variable label `nam' } qui replace `id' = "`nam'" in `i' local i = `i' + 1 local ii = `ii' + 1 } qui compress `id' if "`generat'"=="" { tempname generat } qui gen str20 `generat' = "" gen long `vv' = _n sort `bb' `vv' /* we would like vv2 to be such that when sorted by vv, vv2 would point to the list of contrasts in order. In other words, vv2[i] would identify the i-th item in the list. This would happen if we could compute vv2[vv] = _n vv bb rank vv2 vv, when sorted by bb 1 1.2 3 2 2 2 0.6 1 3 3 3 0.8 2 1 1 an easy solution would be to save vv in the present sorted order and merge it back after resorting by vv! */ tempfile USER VV cap drop _merge qui save `USER' qui keep `vv' rename `vv' `vv2' cap save `VV', replace qui use `USER', clear sort `vv' qui merge using `VV' drop _merge local i 1 local g 1 local top 0 while `i' <= `numcat' { local j = `i'+1 local cont 1 while (`j' <= `numcat') & `cont' { local ii = `i' while `ii'<`j' { local i1 = min(`vv2'[`ii'],`vv2'[`j']) local j1 = max(`vv2'[`ii'],`vv2'[`j']) local pat = (`j1'-1)*(`j1'-2)/2 + `i1' local p = `1'[`pat'] if (`p' <= `cutoff') { local cont 0 } local ii = `ii' + 1 } if `cont' { local j = `j' + 1 } } * At this point, we have identified a group running from i to j-1 * such that all of these objects are within the cutoff P of each * other. We dont yet know if they were included in a similar * group with a lower value of i. the variable "top" will tell us if (`top'<`j'-1) { local top = `j'-1 local ii `i' local sym = substr("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwyz",mod(`g'-1,62)+1,1) di "Group `sym'" while `ii'<`j' { local k = `vv2'[`ii'] di " " `id'[`k'] local ks = `generat'[`k'] qui replace `generat' = substr("`ks'`sym'",1,20) in `k' local ii = `ii' + 1 } local g = `g' + 1 } local i = `i' + 1 } qui compress `generat' end