*! outdisp.ado Version 6.3 RL Kaufman 11/14/2018 *** 1.0 Adapted from effdisp.ado (version 2.0) *** Works with standard MAIN INT2 INT3 option specification. Use DEFINEFM.ADO to define focal & moderator vars & properties *** MAIN string contains (varlist1, name(word) cat range(numlist)) (varlist2, name(word) cat range(numlist) ... ) *** NDIGITS(#) for format default=4. abbrev(#) is # characters in abbreviated Stata names (default 10) in headings, labels, etc. *** EQName(string) is the name/# of alternative to 1st equation results *** *** OUTcome(metric(name) atopt(string) dualaxis mainest(name)) METRIC specifies metirc for predicted values, name = MODEL metric or OBS metric(default). *** ATOPT specifies reference values for all vars except Focal & modreating. (ASOBS) (MEANS) or v1= v2= specifcations allowed. Default=asobs *** DUALaxis is valid only for MODEL metric and adds 2nd y-axis labelled in observed metric. *** MAINest is valid only for OBSERVED metric bar charts or scatterplots and adds/superimposes main effect model predictions, *** name = estimates name where main effects model results are stored *** *** PLOT(type(name) single name(name) gen(name) save(filepath) freq(name) keepfrq). TYPE default is *** Bar Charts for nominal FOCAL & M1 freq *** Scatterplot for mixed nominal-interval FOCAL & M1 [x-axis = interval variable]. *** SINGLE option only for scatterplot, 1= indvidual plots by values of Mod1 (default is multiple curves on same plot) *** 2=indvidual plots by MOD2 (default is pairs/triplets on same graph), all = both *** Contour plot for interval FOCAL & M1 . LEVELS option only for contour plot; defines contour cutpoints. *** NAME is graph name. OPTION GEN never implemented{{ GEN(name) is name=varstub for saving plot info as vars. }} *** SAVE saves matrices with plotinfo to filepath. FREQ attaches relative freq distn plot to each outcome display plot *** (side by side smaller contour for contour plot), name specifies base: SUB= FOCAL by M1 with base defined by subsamples of M1; *** SUBTOT = FOCAL by M1 base defined by total sample. KEEPfrq = do not delete freq distn subplots after combining. *** *** TABle(row(name) save(filepath) freq(name)). ROW specifies if FOCAL or M1 defines table rows/cols; NAME = FOCAL or MOD, default is MOD. *** SAVE saves tables to filepath. FREQ adds second table with relative freq distn below each outcome table; *** name specifies base: SUB= FOCAL by M1 with base defined by subsamples of M1; SUBTOT = FOCAL by M1 base defined by total sample. *** *** SAVE to XLSX not xls to avoid problem of too many fonts error and incomplete formatting *** *** 2.0 Made separate ado file MKMARGVAR.ADO to make variables from margins results for creating tables and graphs *** *** 3.0 Added preserve, put quiet on, removed checking code and generally cleaned up code. **** Added to PLOT() syntax OPTS(asis) to allow user options, excludes LEVELS as separate option. *** UNDOCUMENTED OPTION: MYGLOB(KEEP) so I can check easily. Added SUMWGT(no) option so user can requested use of unweighted summary statistics. *** 4.0 Adapted to use intspec.ado to set-up and save the globals for the interaction specification for re-use. SUMWGT now INTSPEC option *** 4.1 For dual-axis option changed to use y-standardized prediction outcome in model metric *** 5.0 Added mlogit functionality, made pred value table produced by default if neither table() or plot(() specified *** 5.1 SDY option allows y-standardized metric w or w/o dual, for mlogit separate latent variable std dev for each ln odds contrast *** 5.2 Saves table to Excel with font size scaled to predicted value *** 5.3 CCUTS option allows user specified contour cutpoints *** 5.4 Corrected caculation of standardized ln(Count) and corrected capability to analyze inflate component of ZIP and ZINB *** 5.5 Removed ZIP and ZINB from list for which standardized g(y) can be calculated. mean and s.d. of ln(count) are expecations of compund of 2 random vars *** 6.0 Add functionality for observed metric (prob) tables and figures. Corrected y-standardized predicted outcome for logit/probit & ordered logit/probit *** to subtract mean (only consequence is to change Predicted Y-standardized in model metric by a constant *** 6.0 Add functionality for scatter plot to use nominal focal to define multiple prediction lines and mvar1 to define x-axis *** 6.1 Added option TABABS for table font size to be based on absolute value or not *** 6.2 Fixed use of type(scat) for nominal focal variable to switch role of focal and 1st moderator when focal has 2 categories, nnot just >2 *** 6.3 Fixed problem of file paths with embedded blanks in save() option. DO NOT PUT " " AROUND THE FILEPATH for OUTDISP. *** MUST use " " AROUND THE FILEPATH for SIGREG program outdisp, rclass sortpreserve version 14.2 syntax , [ OUTcome(string) plot(string) TABle(string) NDIGits(integer 4) CCUTS(string asis) pltopts(string asis) blabopts(string asis) ] tempname frqmat hold estint h2 mzz tempvar predy1 abspred pred predy1mn predzi predstd fvar mvar1 mvar2 mvar3 mvar4 mvar5 mvar6 fvarmn mvarmn1 mvarmn2 mvarmn3 mvarmn4 mvarmn5 mvarmn6 fvarzi mvar1zi mvar2zi mvar3zi mvar4zi qui { *** check if globsave file created by instspec.ado & definefm.ado if fileexists("`c(tmpdir)'/globsaveeq1$sfx2.do") ==0 { noi disp "{err: Must run intspec.ado to setup and save interaction specification first}" exit } *** PRESERVE DATA & CURRENT ESTIMATES ON EXIT preserve est store `estint' *** load globals from eq1 to use in setup and if-branching capture drop esamp$sfx qui run `c(tmpdir)'/globsaveeq1$sfx2.do *** Get outcome options OUTMETRIC, OUTDUAL, OUTMAIN, OUTSDY if "`outcome'" != "" { foreach nm in metric atopt dual main sdy { loc out`nm' "" } loc hout=strtrim(stritrim(`"`outcome'"')) while `"`hout'"' != "" & `"`hout'"' != " " { gettoken outopt hout : hout , bind match(pp) tokenize `outopt', parse("()") foreach nm in metric atopt dual main sdy { if strmatch("`1'","`nm'*"){ loc out`nm' `"`3'"' if strmatch("`nm'","dual") loc outdual "dual" if strmatch("`nm'","sdy") loc outsdy "sdy" if "`nm'" == "atopt" & "`3'" == "(" { gettoken xx outopt : outopt , parse("(") gettoken xx outopt : outopt , match(pp) loc outatopt "`xx'" } } } } } if "`outmetric'" == "" loc outmetric "obs" if "`outatopt'" == "" loc outatopt "(asobs) _all" *** Get table options TABROW, TABSAVE, TABFREQ, TABABS if `"`table'"' == "" & `"`plot'"' == "" loc table "default" if `"`table'"' != "" { foreach nm in row save freq abs { loc tab`nm' "" } loc htab=strtrim(stritrim(`"`table'"')) while `"`htab'"' != "" & `"`htab'"' != " " { gettoken tabopt htab : htab , bind match(pp) tokenize `tabopt', parse("()") foreach nm in row save freq abs { if strmatch("`1'","`nm'*"){ loc tab`nm' `"`3'"' if strmatch("`nm'","abs") loc tababs "abs" } } } if "`tabrow'" == "" loc tabrow "focal" } *** Get plot options PLTTYPE, PLTSING PLTNAME, PPLTSAVE PLTKEEP PLTFREQ & PLOTOPTS if `"`plot'"' != "" { foreach nm in type sing name save keep freq { loc plt`nm' "" } loc hplot=strtrim(stritrim(`"`plot'"')) while `"`hplot'"' != "" & `"`hplot'"' != " " { gettoken plotopt hplot : hplot , bind match(pp) tokenize `plotopt', parse("()") foreach nm in type sing name save keep freq { if strmatch("`1'","`nm'*"){ loc plt`nm' `"`3'"' if "`nm'" == "keep" loc pltkeep "keep" } } } } * *** Check pltopts for ylab & use to set predy max and min for axis / zlab if contour if `"`pltopts'"' != "" { foreach nm in ylab1 ylab2 zlab1 zlab2 { loc tab`nm' "" } loc nylab=0 loc nzlab=0 loc hplt=strtrim(stritrim(`"`pltopts'"')) while `"`hplt'"' != "" & `"`hplt'"' != " " { gettoken plt hplt : hplt , bind match(pp) foreach nm in ylab zlab { if strmatch(`"`plt'"',"`nm'*") { gettoken gg plt : plt , parse("(") gettoken plt1 gg : plt , match(pp) parse("()") if strmatch(`"`plt1'"',"*add*") == 0 & strmatch(`"`plt1'"',"*axis(2)*") == 0 { loc ++n`nm' loc `nm'`n`nm'' `"`plt1'"' } if strmatch(`"`plt1'"',"*add*") == 1 & strmatch(`"`plt1'"',"*axis(2)*") == 0 { loc ++n`nm' gettoken plt2 gg : plt1 , parse(",") loc `nm'`n`nm'' `"`plt2'"' } } } } } glob ypredmin$sfx "" glob ypredmax$sfx "" if `"`ylab1'"' != "" & strmatch(`"`ylab1'"',"*none*") == 0 & strmatch(`"`ylab1'"',"*,*") ==0 { numlist "`ylab1' `ylab2'" , sort loc nn "`r(numlist)'" glob ypredmin$sfx : word 1 of `nn' loc nlst: list sizeof nn glob ypredmax$sfx : word `nlst' of `nn' } glob zpredmin$sfx "" glob zpredmax$sfx "" if `"`zlab1'"' != "" { numlist "`zlab1' `zlab2'" , sort loc nn "`r(numlist)'" glob zpredmin$sfx : word 1 of `nn' loc nlst: list sizeof nn glob zpredmax$sfx : word `nlst' of `nn' } * *** set PLTTYPE & LEVELS for CONTOUR to defaults if not specified. All other options have no defaults: Not done if not specified if "`plttype'" == "" | strmatch("`plttype'","def*") ==1 { loc plttype "scat" if "${fviscat$sfx}" == "y" | "${fisfv$sfx}" == "y" loc plttype "bar" } loc scatrev "n" if "`plttype'" == "scat" & ("${fviscat$sfx}" == "y" | "${fisfv$sfx}" == "y" ) { if ("${mviscat1$sfx}" == "y" | ("${misfv1$sfx}" == "y" & ${mcnum1$sfx} > 1 ) ) { noi disp as err "Focal Variable (${fvldisp$sfx}) and first Moderator (${mvldisp1$sfx}) both categorical (> 2 categories), one must be interval for a scatter Plot" exit } loc scatrev "y" noi disp as res "Scatterplot uses first Moderator (${mvldisp1$sfx}) as x-axis and Focal Variable (${fvldisp$sfx}) to define separate prediction lines" } if "`plttype'" == "contour" & ( ("${mviscat1$sfx}" == "y" | ("${misfv1$sfx}" == "y" & ${mcnum1$sfx} > 1 ) ) | /// ("${fviscat$sfx}" == "y" | ("${fisfv$sfx}" == "y" & ${fcnum$sfx} > 1 ) ) ) { noi disp as err "Moderator 1 (${mvldisp1$sfx}) and/or Focal Variable (${fvldisp$sfx}) is categorical (> 2 categories) but must be interval for a contour Plot" exit } * ** set matsize if too small for plots loc msz = 676 if "`plttype'" == "contour" & ${mvarn$sfx} > 1 { loc m2n: list sizeof global(mvrange2$sfx) loc msz = 676*`m2n' } if `c(max_matsize)' < `msz' { noi disp in red "maximum matsize < minimum needed (676) for plot" exit } if `c(matsize)' < `msz' set matsize `msz' *** Report back options specified ******************************************************* noi disp _newline as txt "{ul:Outcome Options Specified or Default}" _newline loc nospec "true" foreach nm in type metric atopt dual main sdy { if "`out`nm''" != "" { noi disp as txt " `nm' = " as res " `out`nm''" loc nospec "false" } } if "`nospec'" == "true" noi disp "None specified" if "`tabrow'" != "" { noi disp _newline as txt "{ul:Table Options Specified or Default}" _newline foreach nm in row save freq abs { if "`tab`nm''" != "" /// noi disp as txt " `nm' = " as res " `tab`nm''" } } if `"`plot'"' != "" { noi disp _newline as txt "{ul:Plot Options Specified or Default}" _newline foreach nm in type sing name gen save keep freq { if "`plt`nm''" != "" /// noi disp as txt " `nm' = " as res " `plt`nm''" } } * *** Check consistency of outcome options if "`outmetric'" == "obs" & "`outdual'" != "" { noi disp _newline as err "Dualaxis option not valid for outcome in observed metric. Ignored." as text " " loc outdual "" } foreach modnm in mlogit oprobit ologit { if "`e(cmd)'" == "`modnm'" & "`outdual'" != "" { noi disp _newline as err "Dualaxis option not valid for `modnm' analysis. Ignored." as text " " loc outdual "" } } if "`outmetric'" == "obs" & "`outsdy'" != "" { noi disp _newline as err "SDY option not valid for outcome in observed metric. Ignored." as text " " loc outsdy "" } if ("`e(cmd)'" == "zip" | "`e(cmd)'" == "zinb" ) & "`outsdy'" != "" { noi disp _newline as err "SDY option not valid for ZIP or ZINB. Ignored." as text " " loc outsdy "" } if "`outmetric'" == "model" & "`outmain'" != "" { noi disp _newline as err "Added main effects option not valid for outcome in model metric. Ignored." as text " " loc outmain "" } if "`outmain'" != "" & "`plttype'" == "contour" { noi disp _newline as err "Added main effects option not valid for contour plot. Ignored." as text " " loc outmain "" } * loc grphnmroot "`pltname'" if "`pltname'" == "" loc grphnmroot =strtoname("${fvldisp$sfx}_${mvarn$sfx}Mods") *** Get std dev of y-star or ln y if SDY specified loc ystand "no" loc ystandtxt "" glob ystd$sfx = 1 glob ymn$sfx = 0 if "`outsdy'" == "sdy" & (inlist("`e(cmd)'","logit","logistic","ologit","probit") ==1 /// | inlist("`e(cmd)'","oprobit","mlogit","poisson","nbreg"/*,"zip","zinb"*/)==1 ) { loc ystand "yes" loc ystandtxt "-Standardized" predict `predstd' if esamp$sfx, xb qui sum `predstd' if esamp$sfx if inlist("`e(cmd)'","logit","logistic","ologit","probit","oprobit")==1 { loc errvar = 1 if inlist("`e(cmd)'","logit","logistic","ologit") ==1 loc errvar = _pi^2/3 glob ystd$sfx = (`r(Var)' + `errvar')^.5 glob ymn$sfx = `r(mean)' } if inlist("`e(cmd)'","poisson","nbreg"/*,"zip","zinb"*/)==1 { qui sum `e(depvar)' if esamp$sfx glob ymn$sfx =ln(`r(mean)') glob ystd$sfx = (`r(Var)'/`r(mean)'^2)^.5 } } loc mstp = ${mvarn$sfx} *** If Freq Dist requested construct matrix if "`pltfreq'" != "" | "`tabfreq'" != "" { loc frqopt "`pltfreq'" if "`pltfreq'" == "" loc frqopt "`tabfreq'" if "`pltfreq'" != "" & "`tabfreq'" != "" & "`pltfreq'" != "`tabfreq'" /// noi disp _newline "{error}Warning {res}Frequency options for plot and table differ. Plot frequency option used." frqfocmod1 , freq(`frqopt') mat `hold' = r(frqmat) mat `frqmat' = `hold'' loc fstp: list sizeof global(fvrange$sfx) loc mstp1: list sizeof global(mvrange1$sfx) loc cn "" forvalues j=1/`mstp1' { loc cn "`cn' ${mvlabm1c`j'$sfx}" } loc cn "`cn' Focal_value" mat colnames `frqmat' = `cn' loc rn "" forvalues i=1/`fstp' { loc rn "`rn' ${fvlabc`i'$sfx}" } mat rownames `frqmat' = `rn' mat `hold' =`frqmat'[.,1..`mstp1'] } * *** Loop over # of Equations ( =1 except for mlogit & others TBD) loc eqitot = ${eqnum$sfx2} if "${ordcatnum$sfx2}" !="" & "`outmetric'" == "obs" loc eqitot = ${ordcatnum$sfx2} loc fopenyet "no" forvalues eqi=1/ `eqitot' { glob eqinow$sfx2 = `eqi' glob eqnow$sfx2: word `eqi' of ${eqlist$sfx2} if "${eqnow$sfx2}" == "${eqbase$sfx2}" & ${eqnum$sfx2} > 1 & ( "`e(cmd)'" != "mlogit" | /// ( "`e(cmd)'" == "mlogit" & "`outmetric'" != "obs" ) ) continue *** load globals created by instspec.ado & definefm.ado capture drop esamp$sfx if "${ordcatnum$sfx2}" == "" qui run `c(tmpdir)'/globsaveeq`eqi'$sfx2.do loc titdv "g(${dvname$sfx})" if "`coeftype'" == "spost" | "`coeftype'" == "factor" loc titdv "${dvname$sfx}" loc dvadd "" loc margout "" if "${ordcatnum$sfx2}" !="" { qui run `c(tmpdir)'/globsaveeq1$sfx2.do loc dvadd ":${eqnow$sfx2}" loc margout "out(`eqi')" } *** calc latent s.d. and meanfor mlogit if sdy axis requested if "`outsdy'" != "" & "`e(cmd)'" == "mlogit" { loc errvar = _pi^2/3 capture drop `predstd' predict `predstd' if esamp$sfx, xb outcome("${eqnow$sfx2}") qui sum `predstd' if esamp$sfx glob ystd$sfx = (`r(Var)' + `errvar')^.5 glob ymn$sfx = `r(mean)' } * if "`outsdy'" != "" { noi disp _newline as txt "Standard deviation of g(${dvname$sfx}) = " as res %8.4f ${ystd$sfx} as txt " "_newline if inlist("`e(cmd)'","poisson","nbreg","logit","logistic","mlogit", "ologit","probit"/*,"zip","zinb"*/) == 1 noi disp as txt " Mean = " as res %8.4f ${ymn$sfx} as txt " "_newline } loc grphnm "`grphnmroot'" if ${eqnum$sfx2} > 1 | ("${ordcatnum$sfx2}" !="" & "`outmetric'" == "obs") loc grphnm "`grphnmroot'_`=substr("${eqnow$sfx2}",1,6)'" loc titdv "${dvname$sfx} `dvadd'" if "`outmetric'" == "model" loc titdv "g(${dvname$sfx})" *** If Save plot or table requested, Set up save spreadsheet & save Freq Dist if used if "`pltsave'" != "" | "`tabsave'" != "" { if "`pltsave'" != "" & "`tabsave'" != "" & "`pltsave'" != "`tabsave'" /// noi disp _newline "{error}Warning {res}Save path/file name for plot and table differ. Plot path/file name used." loc savenm `"`pltsave'"' if "`pltsave'" == "" loc savenm `"`tabsave'"' if strpos("`savenm'",".") == 0 loc savenm `"`savenm'.xlsx"' glob plotnum$sfx=0 if "`pltsave'" != "" noi disp _newline as txt "Plot data written to sheet {res:{it:plotdata_${eqnow$sfx2}}} of " as res "`savenm'" if "`tabsave'" != "" noi disp _newline as txt "Table data written to sheet {res:{it:table_${eqnow$sfx2}}} of " as res "`savenm'" loc repmod "modify" if "`fopenyet'" == "no" { loc repmod "replace" loc fopenyet "yes" } putexcel set "`savenm'" , sheet(frqdistdata, replace) `repmod' putexcel A1 = (" ") putexcel set "`savenm'" , sheet(plotdata_${eqnow$sfx2}, replace) modify putexcel A1 = (" ") putexcel set "`savenm'" , sheet(table_${eqnow$sfx2}, replace) modify putexcel A1 = (" ") mata: b=xl();b.load_book("`savenm'"); b.set_sheet("plotdata_${eqnow$sfx2}"); b.set_mode("open"); b.set_column_width(2,2,40);b.set_text_wrap(2,2,"on") if "`pltfreq'" != "" | "`tabfreq'" != "" { noi disp _newline as txt "Frequency distribution data written to sheet {res:{it:frqdistdata}} of " as res "`savenm'" putexcel set "`savenm'" , sheet(frqdistdata) modify putexcel B2 = mat(`frqmat'[.,1..`mstp1']) , names putexcel B2 = ("${fvldisp$sfx}") C1 = ("${mvldisp1$sfx}") , italic loc rown = 3+(2+`fstp') mata: fmat=st_matrix("`hold'"); fsum= sum(fmat); fsumcol = colsum(fmat); st_numscalar("fsum",fsum); st_matrix("fsumcol",fsumcol); mat `h2' = `hold'*100/fsum putexcel B`=`rown'+2' = mat(`h2') , names nform(".0") mat `h2' = `hold' forvalues i=1/`fstp' { forvalues j=1/`mstp1' { sca hhh = 100/el("fsumcol",1,`j') mat `h2'[`i',`j'] = `hold'[`i',`j']*hhh } } putexcel B`=2*`rown'+1' = mat(`h2') , names nform(".0") putexcel A`rown' = ("Total Percents") A`=2*`rown'-1' = ("Col Percents") putexcel B`=`rown'+2' = ("${fvldisp$sfx}") C`=`rown'+1' = ("${mvldisp1$sfx}") B`=2*`rown'+1' = ("${fvldisp$sfx}") C`=2*`rown'' = ("${mvldisp1$sfx}") , italic } mata: b.set_mode("closed") } *} ***** Set up margins specification info ********************************************************************************** *** Margins at spec invariant except for contour focal and M1 *** Do first for interaction model using ATSPEC.ado and then repeat if main effects added option specified loc outmarg " " if ${eqnum$sfx2} > 1 loc outmarg "outcome(${eqnow$sfx2}) " if "${ordcatnum$sfx2}" !="" loc outmarg "outcome(#`eqi') " if ( ${eqnum$sfx2} == 1 & "`e(cmd)'" == "mlogit") | (("`e(cmd)'" == "zip" | "`e(cmd)'" == "zinb" ) & "${eqname$sfx}" == "inflate" ) loc outmarg "outcome(${eqname$sfx})" if ("`e(cmd)'" == "zip" | "`e(cmd)'" == "zinb" ) & "${eqname$sfx}" == "inflate" & "`outmetric'" == "obs" loc outmarg " pr " if "`outmetric'" == "model" loc outmarg "`outmarg' xb" if "`outmetric'" == "model" & "${ordcatnum$sfx2}" !="" loc outmarg " xb" if "`outmarg'" != " " loc outmarg "predict(`outmarg')" *** Construct atspec for F,M1 and 3way F,M1,M2 depending on type of measure *** (a) factor var (b) interval var (c) all catergorical but not factor vars atspec, outmetric(`outmetric') plttype(`plttype') model(int) int3way(${int3way$sfx}) outatopt(`outatopt') scatrev("`scatrev'") loc atinfo "`r(atinfo)'" loc atinfotab "`r(atinfo)'" if "`plttype'" == "contour" | "`plttype'" == "scat" loc atinfotab "`r(atinfotab)'" ******************************************************************************************************************* **** Table of predicted values if specified loc nowgt "noweights" if "${sumwgt$sfx}" != "" loc nowgt "" if `"`table'"' != "" { glo adjzi$sfx = 0 est restore `estint' if ("`e(cmd)'" == "zip" | "`e(cmd)'" == "zinb" ) & "`outmetric'" == "model" { margins if esamp$sfx ${sumwgt$sfx} , predict(pr) at((means) _all) `nowgt' mat h3 = r(b) glo adjzi$sfx = h3[1,1] est restore `estint' } margins if esamp$sfx ${sumwgt$sfx} , `outmarg' `atinfotab' post nose `nowgt' mkmargvar intmod notplot `predy1' `fvar' `mvar1' "n" `mvar2' `mvar3' `mvar4' est restore `estint' ***** standardize predicted outcome if outmetric = model and SDY option and **** adjust predicted outcome in model metric if ZIP or ZINB by ln(1-pr(always zero))]] sort `mvar1' `fvar' if ("`e(cmd)'" == "zip" | "`e(cmd)'" == "zinb") & "`outmetric'" == "model" & "${eqname$sfx}" != "inflate" replace `predy1' = `predy1'+ln(1-${adjzi$sfx}) if `mvar1' < . if "`ystand'" == "yes" replace `predy1' = (`predy1'- ${ymn$sfx}+ ln(1-${adjzi$sfx}))/${ystd$sfx} if `mvar1' < . loc titxt "${dvname$sfx}" if "`outmetric'" == "model" loc titxt "g(${dvname$sfx})`ystandtxt'" if ("`e(cmd)'" == "mlogit" | "${ordcatnum$sfx2}" !="") & "`outmetric'" == "obs" loc titxt "`e(depvar)'[${eqnow$sfx2}]" if ${eqnum$sfx2} == 1 & "`e(cmd)'" == "mlogit" & "`outmetric'" == "obs" loc titxt "`e(depvar)'[${eqname$sfx}]" loc rowvar "`mvar1'" loc colvar "`fvar'" loc rownam "${mvldisp1$sfx}" loc colnam "${fvldisp$sfx}" if "`tabrow'" == "focal" { loc rowvar "`fvar'" loc colvar "`mvar1'" loc rownam "${fvldisp$sfx}" loc colnam "${mvldisp1$sfx}" } levelsof `colvar' , loc(cloop) loc colnum: list sizeof cloop levelsof `rowvar' , loc(rloop) loc rownum: list sizeof rloop if ${mvarn$sfx} == 1 { noi disp _newline(2) "Predicted Value of `titxt' by the Interaction of ${fvldisp$sfx} with ${mvldisp1$sfx}." _newline noi tabdisp `rowvar' `colvar' if `mvar1' < . , stubwidth(18) c(`predy1') format(%10.`ndigits'f) concise cellwidth(9) loc titsav "`titxt' by the Interaction of ${fvldisp$sfx} with ${mvldisp1$sfx}." } if ${mvarn$sfx} == 2 { loc titxt2 "by the Two-way Interactions of ${fvldisp$sfx} with" _newline " ${mvldisp1$sfx} and with ${mvldisp2$sfx}." if "${int3way$sfx}" == "y" /// loc titxt2 "by the Three-way Interaction of ${fvldisp$sfx}, " _newline " ${mvldisp1$sfx} and ${mvldisp2$sfx}." noi disp _newline(2) "Predicted Value of `titxt' `titxt2'" _newline noi tabdisp `rowvar' `colvar' if `mvar1' < . , stubwidth(18) c(`predy1') by(`mvar2') format(%10.`ndigits'f) concise cellwidth(9) loc titsav "`titxt' by the Two-way Interactions of ${fvldisp$sfx} with ${mvldisp1$sfx} and with ${mvldisp2$sfx}." if "${int3way$sfx}" == "y" /// loc titsav "`titxt' by the Three-way Interaction of ${fvldisp$sfx}, ${mvldisp1$sfx} and ${mvldisp2$sfx}." } if ${mvarn$sfx} > 2 { noi disp _newline(2) "Predicted Value of `titxt' by the Two-way Interactions of ${fvldisp$sfx} with " _newline " ${mvldisp1$sfx}, ${mvldisp2$sfx} and ${mvldisp3$sfx}." _newline levelsof `mvar3', loc(mm3lst) loc titsav "`titxt' by the Two-way Interactions of ${fvldisp$sfx} with ${mvldisp1$sfx}, ${mvldisp2$sfx} and ${mvldisp3$sfx}." loc pn=0 foreach mm3 of numlist `mm3lst' { loc ++pn noi disp "Panel `pn': ${mvldisp3$sfx} = ${mvlabm3c`pn'$sfx}" noi tabdisp `rowvar' `colvar' if `mvar1' < . & `mvar3' == `mm3' , stubwidth(18) c(`predy1') by(`mvar2') format(%10.`ndigits'f) concise cellwidth(9) noi disp _newline(2) } } **************************************************Save table ******************************** if "`tabsave'" != "" { capture: drop ``tababs'pred' gen ``tababs'pred' = `tababs'(`predy1') if `mvar1' < . _pctile ``tababs'pred' if `mvar1' < . , percentiles(20 40 60 80) forvalues qt=2/5 { loc qt`qt' =`r(r`=`qt'-1')' } *** Set cutpoints for differential font size qui sum ``tababs'pred' if `mvar1' < . , meanonly loc qt1 = `r(min)' -.5 loc qt6 = `r(max)' +.5 loc sortord "" if ${mvarn$sfx} == 2 loc sortord " `mvar2' " if ${mvarn$sfx} == 3 loc sortord " `mvar3' `mvar2' " sort `colvar' `sortord' `rowvar' levelsof `colvar' , loc(cloop) loc combtxt "mat `h2' = [ " sca m1st = 0 foreach jj of numlist `cloop' { mkmat `predy1' if `colvar' == `jj' , nomiss mat(`mzz'`jj') matname `mzz'`jj' `colvar'`jj', col(1) explicit if m1st == 0 loc combtxt "`combtxt' `mzz'`jj' " if m1st != 0 loc combtxt "`combtxt' , `mzz'`jj' " sca m1st = 1 } `combtxt' ] forvalues mi=1/3 { loc m`mi'stp = 1 if `mi' <= `mstp' { levelsof `mvar`mi'' , loc(hold`mi') loc m`mi'stp: list sizeof hold`mi' } } putexcel set "`savenm'" , sheet(table_${eqnow$sfx2}) modify putexcel B2 = ("`titsav'") loc nrw = 4 loc ncol = inrange(${mvarn$sfx},2,10) loc nform "#####.0000" if `ndigits' != 4 { loc nform "" forvalues nfi=1/`=9-`ndigits'' { loc nform "`nform'#" } loc nform "`nform'." forvalues nfi=1/`ndigits' { loc nform "`nform'0" } } mata: b=xl();b.load_book("`savenm'"); b.set_sheet("table_${eqnow$sfx2}"); b.set_mode("closed"); b.set_column_width(2,`=2+`ncol'+`colnum'',13);b.set_row_height(2,`=2+`m3stp'*(3+`m2stp'*(`rownum'+1))+5',25);b.set_font((2,`=2+`m3stp'*(3+`m2stp'*(`rownum'+1))+5'),(2,`=2+`colnum'+2'),"calibri",11) forvalues m3=1/`m3stp' { if `m3stp' > 1 { putexcel B`nrw' = ("Panel `m3': ${mvldisp3$sfx} = ${mvlabm3c`m3'$sfx}") italic loc ++nrw } putexcel (B`nrw':`=char(66+`ncol'+`colnum')'`nrw') , border(top,medium) putexcel (B`=`nrw'+1':`=char(66+`ncol'+`colnum')'`=`nrw'+1') , border(bottom,medium) putexcel (`=char(66+`ncol'+1)'`nrw':`=char(66+`ncol'+`colnum')'`nrw' ) = "`colnam'" , merge hcenter underline loc ++nrw if ${mvarn$sfx} > 1 putexcel B`nrw' = ("${mvldisp2$sfx}") , left putexcel (`=char(66+`ncol')'`=`nrw'-1':`=char(66+`ncol')'`=`nrw'+(`m2stp'*(`rownum'+`ncol'))') , border(right,medium) putexcel `=char(66+`ncol')'`nrw' = ("`rownam'") , left forvalues cj=1/`colnum' { if "`tabrow'" == "mod" putexcel `=char(66+`ncol'+`cj')'`nrw' = ("${fvlabc`cj'$sfx}") , right if "`tabrow'" == "focal" putexcel `=char(66+`ncol'+`cj')'`nrw' = ("${mvlabm1c`cj'$sfx}") , right } loc ++nrw forvalues m2=1/`m2stp' { if ${mvarn$sfx} > 1 { putexcel B`nrw' = ("${mvlabm2c`m2'$sfx}") , left loc ++nrw } forvalues ri = 1/`rownum' { if "`tabrow'" == "mod" putexcel `=char(66+`ncol')'`nrw' = ("${mvlabm1c`ri'$sfx}") , left if "`tabrow'" == "focal" putexcel `=char(66+`ncol')'`nrw' = ("${fvlabc`ri'$sfx}") , left loc ++nrw } loc nrw = `nrw' - `rownum' putexcel `=char(66+`ncol'+1)'`nrw'= mat(`h2'[`=1+(`m3'-1)*(`m2stp'*`rownum')+(`m2'-1)*`rownum''..`=`rownum'+(`m3'-1)*(`m2stp'*`rownum')+(`m2'-1)*`rownum'',1..`colnum']) , nform(`nform') forvalues fnti=1/`rownum' { forvalues fntj=1/`colnum' { loc fsz=11 forvalues fsi=2/6 { if `tababs'(`h2'[`=`fnti'+(`m3'-1)*(`m2stp'*`rownum')+(`m2'-1)*`rownum'',`fntj']) >= `qt`=`fsi'-1'' & `tababs'(`h2'[`=`fnti'+(`m3'-1)*(`m2stp'*`rownum')+(`m2'-1)*`rownum'',`fntj']) < `qt`fsi'' loc fsz= 10+`fsi' } if `qt6'-.5 <= 0 loc fsz = 27 - `fsz' putexcel `=char(66+`ncol'+`fntj')'`=`nrw'+`fnti'-1' , font(calibri ,`fsz') } } loc nrw = `nrw' + `rownum' } putexcel (B`nrw':`=char(66+`ncol'+`colnum')'`nrw') , border(top,medium) loc ++nrw } } } ******************************************************************************************************** *** Create Plot if Requested if `"`plot'"' != "" { est restore `estint' glo adjzi$sfx = 0 if ("`e(cmd)'" == "zip" | "`e(cmd)'" == "zinb" ) & "`outmetric'" == "model" { margins if esamp$sfx ${sumwgt$sfx} , predict(pr) at((means) _all) `nowgt' mat h3 = r(b) glo adjzi$sfx = h3[1,1] est restore `estint' } margins if esamp$sfx ${sumwgt$sfx} , `outmarg' `atinfo' post nose `nowgt' mat hold= e(at) mkmargvar intmod `plttype' `predy1' `fvar' `mvar1' `scatrev' `mvar2' `mvar3' `mvar4' est restore `estint' ***** standardize predicted outcome if outmetric = model and SDY option [[REMOVED adjust if ZIP or ZINB by ln(1-pr(always zero))]] if ("`e(cmd)'" == "zip" | "`e(cmd)'" == "zinb") & "`outmetric'" == "model" & "${eqname$sfx}" != "inflate" replace `predy1' = `predy1'+ln(1-${adjzi$sfx}) if `mvar1' < . if "`ystand'" == "yes" replace `predy1' = (`predy1'- ${ymn$sfx}+ ln(1-${adjzi$sfx}) )/${ystd$sfx} if `mvar1' < . glob frevcode$sfx "`r(frevcode)'" forvalues i=1/`mstp' { glob m`i'revcode$sfx "`r(m`i'revcode)'" } if "`outmain'" != "" & "`outmetric'" == "obs" { estimates restore `outmain' atspec, outmetric(`outmetric') plttype(`plttype') model(main) int3way(${int3way$sfx}) outatopt(`outatopt') scatrev("`scatrev'") loc atinfo "`r(atinfo)'" margins if esamp$sfx ${sumwgt$sfx} , `outmarg' `atinfo' post nose `nowgt' mkmargvar main `plttype' `predy1mn' `fvarmn' `mvarmn1' `scatrev' `mvarmn2' `mvarmn3' `mvarmn4' est restore `estint' } *** Set loop stops for M2,.. M6... if exist & set to 1 if Not Spec . Pass to plot programs. *** forvalues i=2/6 { loc mod`i' "" loc mstp`i' = 1 if ${mvarn$sfx} >= `i' { levelsof `mvar`i'' , loc(mval`i') loc mstp`i': list sizeof mval`i' loc mod`i' = `i' } } ***************************************************************************************************************************** *** LOOP Over Moderators if > 2 Current functionality only allows 2 moderators. REVISE LATER glo grnames$sfx "" glo pannum$sfx=0 *** FRQTXT TITXT MODTXT MAINTXT MLABTXT used to specify options/info for plot commands . PANTXT used for panel labelling if mods>2 loc frqtxt "" if "`pltfreq'" != "" loc frqtxt "frqmat(`frqmat') base(`pltfreq')" loc dvtxt "${dvname$sfx}" if "`outmetric'" == "model" loc dvtxt "g(${dvname$sfx})`ystandtxt'" if ("`e(cmd)'" == "mlogit" | "${ordcatnum$sfx2}" !="") & "`outmetric'" == "obs" loc dvtxt "`e(depvar)'[${eqnow$sfx2}]" if ${eqnum$sfx2} == 1 & "`e(cmd)'" == "mlogit" & "`outmetric'" == "obs" loc dvtxt "`e(depvar)'[${eqname$sfx}]" if ${mvarn$sfx} == 1 { loc titxt "`dvtxt' by the Interaction of " loc titxt2 "${fvldisp$sfx} and ${mvldisp1$sfx}" } if ${mvarn$sfx} == 2 { loc titxt "`dvtxt' by the Two-way Interactions of " loc titxt2 "${fvldisp$sfx} with ${mvldisp1$sfx} and ${fvldisp$sfx} with ${mvldisp2$sfx}" if "${int3way$sfx}" == "y" { loc titxt "`dvtxt' by the Three-way Interaction of" loc titxt2 "${fvldisp$sfx}, ${mvldisp1$sfx} and ${mvldisp2$sfx}" } } if ${mvarn$sfx} > 2 { loc titxt "`dvtxt' by the Two-way Interactions of" loc titxt2 "${fvldisp$sfx} with ${mvldisp1$sfx}, ${mvldisp2$sfx}" if ${mvarn$sfx} > 3 { forvalues mi=4/`mstp' { loc titxt2 "`titxt2', ${mvldisp`mi'$sfx}" } } loc titxt2 "`titxt2' and ${mvldisp`mstp'$sfx}" } loc titxt3 "`dvtxt' by the Main Effects of" loc modtxt "" loc maintxt "" if "`outmain'" != "" loc maintxt "predmn(`predy1mn') " if ${mvarn$sfx} > 1 { forvalues mi=2/`mstp' { loc modtxt "`modtxt' mvar`mi'(`mvar`mi'')" loc mlabtxt`mi' "" loc pantxt`mi' "" } } * forvalues m3 = 1/`mstp3' { if `mstp3' != 1 { loc mlabtxt3 "mlab3(${mvlabm3c`m3'$sfx})" loc pantxt3 "Panel ${pannum$sfx}: ${mvldisp3$sfx} = ${mvlabm3c`m3'$sfx}" } forvalues m4 = 1/`mstp4' { if `mstp4' != 1 { loc mlabtxt4 "mlab4(${mvlabm4c`m4'$sfx})" loc pantxt4 " and ${mvldisp4$sfx} = ${mvlabm4c`m4'$sfx}" } forvalues m5 = 1/`mstp5' { if `mstp5' != 1 { loc mlabtxt5 " mlab5(${mvlabm5c`m5'$sfx})" loc pantxt5 " and ${mvldisp5$sfx} = ${mvlabm5c`m5'$sfx}" } forvalues m6 = 1/`mstp6' { if `mstp6' != 1 { loc mlabtxt6 " mlab6(${mvlabm6c`m6'$sfx})" loc pantxt6 "`pantxt' and ${mvldisp6$sfx} = ${mvlabm6c`m6'$sfx}" } loc mlabtxt " `mlabtxt3' `mlabtxt4' `mlabtxt5' `mlabtxt6' " loc pantxt " `pantxt3' `pantxt4' `pantxt5' `pantxt6' " if "`plttype'" == "scat" { noi scatyhat , predint(`predy1') fvar(`fvar') mvar1(`mvar1') `modtxt' `maintxt' `mlabtxt' /// dual(`outdual') sdy(`outsdy') outmain(`outmain') scatrev(`scatrev') frqmat(`frqmat') base(`pltfreq') ndig(`ndigits') /// `pltkeep' name(`grphnm') save(`savenm') sing(`pltsing') /// dvtxt(`dvtxt') titxt(`titxt') titxt2(`titxt2') titxt3(`titxt3') pantxt(`pantxt') estint("`estint'") pltopts(`pltopts') } if "`plttype'" == "bar" /// baryhat, predint(`predy1') fvar(`fvar') mvar1(`mvar1') `modtxt' `maintxt' `mlabtxt' /// dual(`outdual') sdy(`outsdy') outmain(`outmain') frqmat(`frqmat') base(`pltfreq') ndig(`ndigits') /// `pltkeep' name(`grphnm') save(`savenm') sing(`pltsing') /// dvtxt(`dvtxt') titxt(`titxt') titxt2(`titxt2') pantxt(`pantxt') estint("`estint'") pltopts(`pltopts') blabopts(`blabopts') if "`plttype'" == "contour" /// contyhat , predint(`predy1') fvar(`fvar') mvar1(`mvar1') `modtxt' `maintxt' `mlabtxt' /// dual(`outdual') sdy(`outsdy') frqmat(`frqmat') base(`pltfreq') ndig(`ndigits') /// `pltkeep' name(`grphnm') save(`savenm') sing(`pltsing') /// dvtxt(`dvtxt') titxt(`titxt') titxt2(`titxt2') pantxt(`pantxt') estint("`estint'") ccuts(`ccuts') pltopts(`pltopts') loc mlabtxt "" loc pantxt "" } } } } } * } drop *$sfx loc mygloblist: all globals "*$sfx" mac drop `mygloblist' * est restore `estint' ** Close quiet loop } end