*! Package mrgtbl2 v. 1.1 *! Support: Niels Henrik Bruun, niels.henrik.bruun@gmail.com *! 2026-01-11 1.1 naming bugs fixed * 2025-12-31 1.0 Revised and send * 2025-12-17 1.0 Created program define mrgtbl2, rclass * The option constraints are added to mixed in version 17.1 and up. * Hence this strange setting of version. if `c(version)' >= 17.1 version 17.1 else version 15.1 syntax [anything(name=regname)] [if], /* */Outcome(passthru) /* */Exposure(passthru) /* */[ /* */By1(passthru) /* */by2(passthru) /* */Adjustments(passthru) /* */Cluster(passthru) /* */CONSTraints(passthru) /* */BOOTstrap(passthru)/* */vce(passthru) /* */Regopts(passthru) /* */Mrgopts(passthru) /* */btext(string) /* */roweq(passthru) /* */noLabel /* */EForm /* */Wide /* */noQuietly /* */] if "`quietly'" == "" local QUIETLY quietly if "`btext'" == "" local btext mrg _regcmd `regname' `if', `outcome' `exposure' `by1' `by2' `adjustments' /// `cluster' `constraints' `bootstrap' `regopts' `mrgopts' local regcmd `r(regcmd)' local mrgcmd `r(mrgcmd)' local outcome `r(outcome)' local exposure `r(exposure)' local by1 `r(by1)' local by2 `r(by2)' local poscmds = `"`r(plst)'"' if "`QUIETLY'" == "" di as input _n `". `regcmd'"' _n `QUIETLY' `regcmd' if "`QUIETLY'" == "" di as input _n `". `mrgcmd'"' _n `QUIETLY' `mrgcmd' estimates store _mrgtbl2 return local regcmd = `"`regcmd'"' return local mrgcmd = `"`mrgcmd'"' return local poscmds = `"`poscmds'"' _mrgtbl2 `exposure', btext(`btext') by1(`by1') by2(`by2') `label' `wide' /// `eform' `roweq' matrix mrgtbl2 = r(mrgtbl2) matlist mrgtbl2, tw(32) return matrix mrgtbl2 = mrgtbl2 end program define _regcmd, rclass syntax [anything(name=regname)] [if], /* */Outcome(varname) /* */Exposure(varname) /* */[ /* */By1(varname) /* */by2(varname) /* */Adjustments(varlist fv) /* */Cluster(varname) /* */CONSTraints(passthru) /* */BOOTstrap(string)/* */vce(passthru) /* */Regopts(string) /* */Mrgopts(string) /* */] if "`regname'" == "" local regname mixed local plst `""regress", "cnsreg", "mixed", "glm", "poisson", "nbreg", "' local plst `"`plst' "logit", "probit", "cloglog", "binreg", "meprobit", "' local plst `"`plst' "melogit", "mepoisson", "menbreg", "meglm", "mecloglog""' if !regexm(`"`plst'"', "`regname'") mata: _error("Chosen regression isn't allowed") if "`bootstrap'" != "" local bootstrap bootstrap, `bootstrap': if `"`cluster'"' != "" local cluster ||`cluster':, if "`by1'" == "" & "`by2'" == "" local expby i.`exposure' else if "`by1'" != "" & "`by2'" == "" local expby i.`exposure'#i.`by1' else if "`by1'" != "" & "`by2'" != "" local expby i.`exposure'#i.`by1'#i.`by2' local regcmd `bootstrap' `regname' `outcome' `expby' `adjustments' `if' /// , `constraints' `vce' `cluster' `regopts' if "`by1'" == "" & "`by2'" == "" local expby `exposure' else if "`by1'" != "" & "`by2'" == "" local expby `exposure'#`by1' else if "`by1'" != "" & "`by2'" != "" local expby `exposure'#`by1'#`by2' local mrgcmd margins `expby', `mrgopts' post return local regcmd `regcmd' return local mrgcmd `mrgcmd' return local outcome `outcome' return local exposure `exposure' return local by1 `by1' return local by2 `by2' return local plst `plst' end program define _row, rclass syntax , Formula(string) /* */[ /* */Pvalue /* */Mrgtext(string) /* */Wide /* */EForm /* */] qui lincom `formula', `eform' if "`pvalue'" == "" { matrix _row = r(estimate), r(lb), r(ub) matrix colnames _row = `mrgtext' [`c(level)'% CI] } else { matrix _row = r(estimate), r(lb), r(ub), r(p) matrix colnames _row = `mrgtext' [`c(level)'% CI] P(`mrgtext') } if mi(`r(lb)') matrix _row = J(1,`=colsof(_row)',.) return matrix row = _row end program define _btbl, rclass syntax varname [if], /* */[ /* */Btext(string) /* */by(string) /* */roweq(string) /* */Label /* (nolabel) */Wide /* */EForm /* */] *qui estimates restore _mrgtbl2 capture matrix drop btbl qui levelsof `varlist' `if' foreach lvl in `r(levels)' { if "`wide'" == "" local btxt `btext' else local btxt `btext'(`lvl') local lbl `:label (`varlist') `lvl'' if "`lbl'" == "" & "`label'" == "" local lbl `varlist'(`lvl') _row, f("`lvl'.`varlist'`by'") m(`btxt') `eform' matrix _row = r(row) if "`wide'" == "" { matrix coleq _row = "" matrix rownames _row = "`=abbrev("`lbl'", 32)'" local btxt `btxt' matrix btbl = nullmat(btbl) \ _row } else { matrix coleq _row = "`=abbrev("`lbl'", 32)'" matrix rownames _row = "" local btxt `btxt' matrix btbl = _row, nullmat(btbl) } } return matrix btbl = btbl end program define _dtbl, rclass syntax varname [if], /* */[ /* */Btext(string) /* */by(string) /* */roweq(string) /* */Label /* (nolabel) */Wide /* */EForm /* */] *qui estimates restore _mrgtbl2 capture matrix drop dtbl local ref qui levelsof `varlist' `if' foreach lvl in `r(levels)' { if "`ref'" == "" { local ref `lvl' continue } local btxt `btext'(vsRef) _row, f("`lvl'.`varlist'`by' - `ref'.`varlist'`by'") p m(`btxt') `eform' matrix _row = r(row) if "`wide'" == "" { matrix rownames _row = "`=abbrev("`btext'(`lvl'vs`ref')", 32)'" matrix dtbl = nullmat(dtbl) \ _row } else { matrix coleq _row = "`=abbrev("`btext'(`lvl'vs`ref')",32)'" matrix dtbl = _row, nullmat(dtbl) } } if "`wide'" == "" { matrix _refrow = J(1,4,.) matrix rownames _refrow = ref matrix colnames _refrow = `:colnames dtbl' matrix dtbl = _refrow \ dtbl } return matrix dtbl = dtbl end program define _mrgtbl2, rclass syntax varname [if] , /* */[ /* */By1(varname) /* */by2(varname) /* */btext(string) /* */roweq(string) /* */noLabel /* */noCounts /* */Wide /* */EForm /* */] *qui estimates restore _mrgtbl2 if "`by1'" == "" & "`by2'" == "" { _btbl `varlist', btext(`btext') `label' `wide' `eform' matrix _mrgtbl2 = r(btbl) _dtbl `varlist', btext(`btext') `label' `wide' `eform' matrix _mrgtbl2 = _mrgtbl2, r(dtbl) if "`roweq'" != "" & "`wide'" == "" matrix roweq _mrgtbl2 ="`=abbrev("`roweq'", 32)'" if "`roweq'" != "" & "`wide'" != "" matrix rownames _mrgtbl2 = "`=abbrev("`roweq'", 32)'" } else if "`by1'" != "" & "`by2'" == "" { capture matrix drop _mrgtbl2 qui levelsof `by1' `if' foreach lvl1 in `r(levels)' { _btbl `varlist', btext(`btext') by(#`lvl1'.`by1') `label' `wide' `eform' matrix _brow = r(btbl) _dtbl `varlist', btext(`btext') by(#`lvl1'.`by1') `label' `wide' `eform' matrix _drow = r(dtbl) mata: st_replacematrix("_drow", st_matrix("_drow") /// :/ (rowmissing(st_matrix("_brow")) :== 0)) if `=_brow[1,2]== .' mata: st_replacematrix("_drow", st_matrix("_drow") :/ 0) matrix _row = _brow, _drow local lbl1 `:label (`by1') `lvl1'' if "`lbl1'" == "`lvl1'" & "`label'" == "" local lbl1 `by1'(`lvl1') if "`wide'" == "" matrix roweq _row = "`lbl1'" else matrix rownames _row = "`=abbrev("`lbl1'", 32)'" matrix _mrgtbl2 = nullmat(_mrgtbl2) \ _row } if "`roweq'" != "" & "`wide'" != "" matrix roweq _mrgtbl2 ="`=abbrev("`roweq'", 32)'" } else if "`by1'" != "" & "`by2'" != "" { capture matrix drop _mrgtbl2 qui levelsof `by2' `if' foreach lvl2 in `r(levels)' { local lbl2 `:label (`by2') `lvl2'' if "`lbl2'" == "`lvl2'" & "`label'" == "" local lbl2 `by2'(`lvl2') qui levelsof `by1' `if' foreach lvl1 in `r(levels)' { _btbl `varlist', btext(`btext') by(#`lvl1'.`by1'#`lvl2'.`by2') /// `label' `wide' `eform' matrix _brow = r(btbl) _dtbl `varlist', btext(`btext') by(#`lvl1'.`by1'#`lvl2'.`by2') /// `label' `wide' `eform' matrix _drow = r(dtbl) mata: st_replacematrix("_drow", st_matrix("_drow") /// :/ (rowmissing(st_matrix("_brow")) :== 0)) if `=_brow[1,2]== .' mata: st_replacematrix("_drow", st_matrix("_drow") :/ 0) matrix _row = _brow, _drow local lbl1 `:label (`by1') `lvl1'' if "`lbl1'" == "`lvl1'" & "`label'" == "" local lbl1 `by1'(`lvl1') if "`wide'" == "" matrix roweq _row = "`lbl2'&`lbl1'" else matrix rownames _row = "`=abbrev("`lbl2'&`lbl1'", 32)'" matrix _mrgtbl2 = nullmat(_mrgtbl2) \ _row } } if "`roweq'" != "" & "`wide'" != "" matrix roweq _mrgtbl2 ="`=abbrev("`roweq'", 32)'" } return matrix mrgtbl2 = _mrgtbl2 end