This is an offshoot of a previous question: Using collect and margins to create custom table - Statalist, but more related to programming than to the collect commands. I am attempting to automate the retrieval of certain information from the margins command with the pwcompare option. Since this is a common task with multiple data sets, I would like to make this as flexible as possible. In order to do so, I need the program to generate a number of collect get commands, the number and content of which will depend on the levels of the factor variable included in the margins statement. (I should say that I am very new to Stata programming, so it's quite possible I've gone down a dead end path.) In any case, here is an example:
I have created a do file called mymargins that is supposed to generate a table of predicted margins, a table of predicted marginal effects and output them to a word document:
The main issue seems to be the commands macro that is created within the do file. The individual commands within the commands macro run, as can be confirmed by the looking at the results of
for example. However, nothing after the commands macro is invoked seems to run although it appears on the console. For example, if you run
it does not include ci, even though it should be created in the collect composite command. In addition, the Word document is not created.
Here is the console output from invoking the mymargins macro
I am using Stata/BE 18.5. Any help would be greatly appreciated.
Colin
Code:
sysuse auto, clear gen pricef = . replace pricef = 1 if price < 7000 replace pricef = 2 if price >= 7000 & price < 10000 replace pricef = 3 if price >= 10000 label define price_lbl 1 "<7000" 2 "7000-10000" 3 "10000+" label values pricef price_lbl reg mpg i.pricef collect create Margins do mymargins pricef
Code:
* Define the variable name and the integer n local varname `1' // Use the levelsof command to get the --levels-- of the factor variable levelsof `varname', local(levels) // Define local macro -- n_levels -- = the number of levels of varname local n_levels: word count `levels' // Define local macro -- m1 -- consisting a string of levels of varname forvalues i = 1/`n_levels' { local m1 "`m1' `i'.`varname'" } // Define local macro -- contrasts -- = to string of all contrasts foreach level1 of local levels { foreach level2 of local levels { if `level1' < `level2' { local contrasts "`contrasts' `level2'vs`level1'.`varname'" } } } // Define local macro -- commands -- consisting of collect get commands to retrieve elements of table_vs for each level of contrasts local j = 1 foreach c of local contrasts { local lb_vs = `"collect get lb_vs= r(table_vs)['ll', `j'], tags(colname[`c'])"' local ub_vs = `"collect get ub_vs= r(table_vs)['ul', `j'], tags(colname[`c'])"' local pvalue = `"collect get pvalue= r(table_vs)['pvalue', `j'], tags(colname[`c'])"' display "`commands'" local commands "`commands' `lb_vs' ; `ub_vs' ; `pvalue' ;" local j = `j' + 1 } collect set Margins // Margins command collect, name(Margins) tag(model[`1']): margins `1', pwcompare(effects) #delimit ; `commands' #delimit cr collect remap result[b_vs lb_vs ub_vs]=result[_r_b _r_lb _r_ub] collect composite define ci = _r_lb _r_ub, delimiter(", ") trim replace collect label levels result ci "95% CI" *collect style use tbl.stjson, name(Margins) override collect label levels result _r_b "Marginal Proportions", modify name(Margins) display "`m1'" collect title "Margins", name(Margins) collect layout (colname[`m1']) (result[_r_b ci]) collect preview putdocx begin putdocx collect collect label levels result _r_b "Marginal Difference(s)", modify name(Margins) collect title "Marginal Effects" collect layout (colname[`contrasts']) (result[_r_b ci pvalue]) putdocx paragraph putdocx text ("Mountain High Report: ") putdocx describe putdocx collect putdocx save test, replace
The main issue seems to be the commands macro that is created within the do file. The individual commands within the commands macro run, as can be confirmed by the looking at the results of
Code:
collect levelsof colname
Code:
collect levelsof result
Here is the console output from invoking the mymargins macro
Code:
. do mymargins pricef . * Define the variable name and the integer n . local varname `1' . . // Use the levelsof command to get the --levels-- of the factor variable . levelsof `varname', local(levels) 1 2 3 . // Define local macro -- n_levels -- = the number of levels of varname . local n_levels: word count `levels' . . // Define local macro -- m1 -- consisting a string of levels of varname . forvalues i = 1/`n_levels' { 2. local m1 "`m1' `i'.`varname'" 3. } . . // Define local macro -- contrasts -- = to string of all contrasts . foreach level1 of local levels { 2. foreach level2 of local levels { 3. if `level1' < `level2' { 4. local contrasts "`contrasts' `level2'vs`level1'.`varname'" 5. } 6. } 7. } . . // Define local macro -- commands -- consisting of collect get commands to retrieve > elements of table_vs for each level of contrasts . local j = 1 . foreach c of local contrasts { 2. local lb_vs = `"collect get lb_vs= r(table_vs)['ll', `j'], tags(colname[ > `c'])"' 3. local ub_vs = `"collect get ub_vs= r(table_vs)['ul', `j'], tags(colname[ > `c'])"' 4. local pvalue = `"collect get pvalue= r(table_vs)['pvalue', `j'], tags(co > lname[`c'])"' 5. display "`commands'" 6. local commands "`commands' `lb_vs' ; `ub_vs' ; `pvalue' ;" 7. local j = `j' + 1 8. } collect get lb_vs= r(table_vs)['ll', 1], tags(colname[2vs1.pricef]) ; collect get ub > _vs= r(table_vs)['ul', 1], tags(colname[2vs1.pricef]) ; collect get pvalue= r(table > _vs)['pvalue', 1], tags(colname[2vs1.pricef]) ; collect get lb_vs= r(table_vs)['ll', 1], tags(colname[2vs1.pricef]) ; collect get ub > _vs= r(table_vs)['ul', 1], tags(colname[2vs1.pricef]) ; collect get pvalue= r(table > _vs)['pvalue', 1], tags(colname[2vs1.pricef]) ; collect get lb_vs= r(table_vs)['ll' > , 2], tags(colname[3vs1.pricef]) ; collect get ub_vs= r(table_vs)['ul', 2], tags(co > lname[3vs1.pricef]) ; collect get pvalue= r(table_vs)['pvalue', 2], tags(colname[3v > s1.pricef]) ; . . collect set Margins (current collection is Margins) . . // Margins command . collect, name(Margins) tag(model[`1']): margins `1', pwcompare(effects) Pairwise comparisons of adjusted predictions Number of obs = 74 Model VCE: OLS Expression: Linear prediction, predict() ---------------------------------------------------------------------------------- | Delta-method Unadjusted Unadjusted | Contrast std. err. t P>|t| [95% conf. interval] -----------------+---------------------------------------------------------------- pricef | 7000-10000 | vs | <7000 | -2.149425 2.253092 -0.95 0.343 -6.641962 2.343112 10000+ vs <7000 | -7.482759 1.798949 -4.16 0.000 -11.06976 -3.895755 10000+ | vs | 7000-10000 | -5.333333 2.713082 -1.97 0.053 -10.74306 .0763977 ---------------------------------------------------------------------------------- . . #delimit ; delimiter now ; . `commands' > #delimit cr > > collect remap result[b_vs lb_vs ub_vs]=result[_r_b _r_lb _r_ub] > collect composite define ci = _r_lb _r_ub, delimiter(", ") trim replace > collect label levels result ci "95% CI" > > *collect style use tbl.stjson, name(Margins) override > collect label levels result _r_b "Marginal Proportions", modify name(Margins) > > display "`m1'" > > collect title "Margins", name(Margins) > collect layout (colname[`m1']) (result[_r_b ci]) > collect preview > > putdocx begin > putdocx collect > > collect label levels result _r_b "Marginal Difference(s)", modify name(Margins) > collect title "Marginal Effects" > collect layout (colname[`contrasts']) (result[_r_b ci pvalue]) > > putdocx paragraph > putdocx text ("Mountain High Report: ") > > putdocx describe > > putdocx collect > putdocx save test, replace > > end of do-file
Colin
Comment