*! xtsum2docx.ado ver.1.7.1 Futoshi Narita 2019/01/18 *! Allow statistics to list in an order specified as: *! order(stat1 stat2 ...), e.g., order(mean sd obs), *! and add two statistics from xtsum, specified as options as follows: *! xtn for r(n), xttbar for r(Tbar), xtsdb for r(sd_b), xtmaxw for r(max_w), *! and so on. *! *! Based on sum2docx.ado - with my huge thanks to the authors! *! The original authors of sum2docx.ado: *! Chuntao LI *! China Stata Club(爬虫俱乐部) *! Wuhan, China *! chtl@zuel.edu.cn *! *! Yuan XUE *! China Stata Club(爬虫俱乐部) *! Wuhan, China *! xueyuan19920310@163.com program define xtsum2docx version 15.0 //使用putdocx,只能在Stata15中使用 syntax varlist(numeric) [if] [in] using/, [append replace title(string) obs OBSfmt(string) /// mean MEANfmt(string) var VARfmt(string) sd SDfmt(string) skewness /// SKEWNESSfmt(string) kurtosis KURTOSISfmt(string) sum SUMfmt(string) min /// MINfmt(string) max MAXfmt(string) p1 P1fmt(string) p5 P5fmt(string) p10 /// P10fmt(string) p25 P25fmt(string) median MEDIANfmt(string) p50 P50fmt(string) p75 P75fmt(string) /// p90 P90fmt(string) p95 P95fmt(string) p99 P99fmt(string) /// xtn XTNfmt(string) xttbar XTTBARfmt(string) /// xtmaxw XTMAXWfmt(string) xtminw XTMINWfmt(string) /// xtmaxb XTMAXBfmt(string) xtminb XTMINBfmt(string) /// xtsdw XTSDWfmt(string) xtsdb XTSDBfmt(string) /// order(string)] // statistics available via summarize (already available for sum2docx), // except for N, median, and Var (which are separately treated): local statlist mean sd skewness kurtosis sum max min p1 p5 p10 p25 p50 p75 p90 p95 p99 // statistics available via xtsum (added for xtsum2docx): local xtstatlist n Tbar max_w min_w max_b min_b sd_w sd_b if "`append'" != "" & "`replace'" != "" { //append和replace不能同时定义 disp as error "You cannot specify both append and replace." exit 198 } tempname post_sum tempfile postsum local varlen = 0 foreach v of varlist `varlist' { if length(`"`v'"') > `varlen' local varlen = length(`"`v'"') } local num = 0 if "`obs'" != "" | "`obsfmt'" != "" { local postvar "`postvar'obs " //如果输出样本量,添加Obs local postcontent `"`postcontent'(r(N)) "' local num = `num' + 1 if "`obsfmt'" == "" local obsfmt %9.0f //Default } if "`var'" != "" | "`varfmt'" != "" { //输出方差 local postvar = "`postvar'var " local postcontent `"`postcontent'(r(Var)) "' local num = `num' + 1 if "`varfmt'" == "" local varfmt %9.1f //Default } if "`median'" != "" | "`medianfmt'" != "" { local postvar = "`postvar'median " local postcontent `"`postcontent'(r(p50)) "' local num = `num' + 1 if "`medianfmt'" == "" local medianfmt %9.1f //Default } // Loop for the same procedure. foreach stat of local statlist { if "``stat''" != "" | "``stat'fmt'" != "" { local postvar = "`postvar'`stat' " local postcontent `"`postcontent'(r(`stat')) "' local num = `num' + 1 if "``stat'fmt'" == "" local `stat'fmt %9.1f //Default } } // Only valid after xtset (or tsset) local flg_panel = 0 foreach xtstat of local xtstatlist { local xtstat2: subinstr local xtstat "_" "", all local xtstat2 = strlower("`xtstat2'") if "`xt`xtstat2''" != "" | "`xt`xtstat2'fmt'" != "" { local postvar "`postvar'xt`xtstat2' " local postcontent `"`postcontent'(xt_r_`xtstat') "' local num = `num' + 1 if "`xt`xtstat2'fmt'" == "" { local xt`xtstat2'fmt %9.1f //Default // Default for xtnfmt is %9.0f if "`xtstat2'" == "n" local xt`xtstat2'fmt %9.0f } local flg_panel = 1 } } // If no statistics is specified, throw an error if length(trim(`"`postvar'"')) == 0 { di as err "At least one statstics must be specified (e.g., mean) in the option." exit 198 } // Re-order statistics based on `order'; if not fully specified, // put listed ones first and the rest is in the order just as above. // Create a local variable "original_order" that contains "1 2 3 ... `num'" local original_order forvalues j=1/`num' { local original_order "`original_order'`j' " } local rest_order `original_order' // Tokenize "postvar" and "postcontent" tokenize `postvar' forvalues j=1/`num' { local v`j' ``j'' } tokenize `postcontent' forvalues j=1/`num' { local c`j' ``j'' } // Create a local variable "re_order" that contains the specified order tokenize `postvar' local re_order local cnt_order: word count `order' forvalues i=1/`cnt_order' { local y: word `i' of `order' forvalues j=1/`num' { if "`y'" == "`v`j''" { local re_order "`re_order'`j' " local rest_order: subinstr local rest_order "`j'" "", word } } } if "`rest_order'" != "" { local re_order "`re_order'`rest_order' " } // Re-order postvar based on `re_order' local re_postvar local re_postcontent tokenize `re_order' forvalues j=1/`num' { local re_postvar "`re_postvar'`v``j''' " local re_postcontent `"`re_postcontent'`c``j''' "' } local postvar `re_postvar' local postcontent `re_postcontent' // Add variable name at the beginning. local postvar "str`varlen' VarName `postvar'" local num = `num' + 1 qui { postfile `post_sum' `postvar' using `postsum.dta', replace foreach var of varlist `varlist' { local postcontent_v "`postcontent'" if `flg_panel' == 1 { xtsum `var' `if' `in' foreach xtstat of local xtstatlist { local xt_r_`xtstat' = r(`xtstat') local postcontent_v: subinstr local postcontent_v "(xt_r_`xtstat')" "(`xt_r_`xtstat'')", word } } sum `var' `if' `in', d post `post_sum' ("`var'") `postcontent_v' } postclose `post_sum' preserve use `postsum.dta', clear local row = _N + 1 // Loop for formating foreach stat in obs var median `statlist' { if "``stat''" != "" | "``stat'fmt'" != "" format ``stat'fmt' `stat' } foreach xtstat of local xtstatlist { local xtstat2: subinstr local xtstat "_" "", all local xtstat2 = strlower("`xtstat2'") if "`xt`xtstat2''" != "" | "`xt`xtstat2'fmt'" != "" format `xt`xtstat2'fmt' xt`xtstat2' } compress capture putdocx clear putdocx begin if `"`title'"' != "" { putdocx paragraph, spacing(after, 0) putdocx text (`"`title'"') } putdocx table sumtable = data("_all"), varnames border(all, nil) border(bottom) border(top) putdocx table sumtable(1,1), border(bottom) forvalues i = 2/`num' { putdocx table sumtable(1,`i'), border(bottom) forvalues j = 1/`row' { putdocx table sumtable(`j',`i'), halign(right) } } if "`replace'" == "" & "`append'" == "" { //如果既没有replace也没有append,直接save putdocx save `using' } else { putdocx save `using', `replace'`append' } restore } end