*! version 1.0.2 08dec2010 Daniel Klein program gdsum ,rclass byable(recall) /*set version*/ if _caller() <11.1 { local vers =_caller() di "{txt}this is version {res}`vers' {txt}of Stata; " /// "{cmd:gdsum}{txt} is a version 11.1 program " /// "and may not work properly" } else version 11.1 /*snytax weights are not documented. I am not yet sure if weights are appropriate this way*/ syntax varlist(numeric) [if] [in] [fw aw iw] /// [,REMove(string asis) MEDian MIN(real 0) MAX(real 1) /// COMma noVARLabel Format(string) MATrix(name)] /*set options*/ if `"`remove'"' !="" local remove `"- `remove'"' else local remove - if "`median'" !="" local p50 p50 else local p50 local dpis =c(dp) if "`comma'" =="" local comma =c(dp) if `"`format'"' !="" { cap confirm form `format' if _rc { di "{err}option format() incorrectly specified" exit 198 } } /*matrices description lv : vector of unique values in variables frq : vector of frequencies xbar : vector of means of classes m : matrix/scalar mean sd : matrix/scalar standard deviation M : output matrix*/ tempname lv frq xbar m sd M tmp /*set ouput matrix*/ local nvars : word count `varlist' if "`median'" !="" local ncols 4 else local ncols 3 mat `M' =J(`nvars',`ncols',.) /*loop over vars*/ local varcount 0 local txtw 12 foreach var of local varlist { if `"`varlabel'"' =="" { local nam : var lab `var' if `"`nam'"' =="" local nam `var' else local nam =subinstr("`nam'",".","",.) } else local nam `var' local ttxtw : length local nam if `ttxtw' >32 { di `"{res}`var'{txt}:{res} "`nam'" "' /// `"{txt}abbreviated to 32 characters"' local nam =abbrev("`nam'" ,32) local ttxtw 32 } if `ttxtw' > `txtw' local txtw `ttxtw' local listofnames `"`listofnames'"`nam'" "' /*mark sample for each var*/ qui cap drop `touse' marksample touse ,novarlist qui replace `touse' =0 if `var' >=. qui count if `touse' if r(N) ==0 { di "{res}`var'{txt}: no observations" continue } /*check value label exists*/ local vallab : val lab `var' if `"`vallab'"' =="" { di "{res}`var'{txt}: no value label" continue } /*set matrices lv and frq*/ qui ta `var' if `touse' [`weight'`exp'] /// ,matrow(`lv') matcell(`frq') local n =r(N) local nrows =rowsof(`lv') /*set empty matrix*/ mat `xbar' =J(`nrows',1,.) /*get median class*/ if "`median'" !="" { qui su `var' [`weight'`exp'] if `touse' ,d local med_cl =floor(r(p50)) } forval j =1/`nrows' { /*get upper and lower bounds*/ local lvl =`lv'[`j',1] local lbl : label `vallab' `lvl' ,strict /*deal with commas*/ if "`comma'" !="comma" local comma_rmv "" else local commarmv "." local lbl =subinstr("`lbl'",",","`commarmv'",.) foreach chr of local remove { local lbl =subinstr("`lbl'","`chr'"," ",.) } if "`lbl'" =="" { di "{res}`var'{txt}=={res}`lvl'{txt} not labeled" continue } tokenize `lbl' /*correct first and last bounds*/ if `j' == 1 & "`2'" =="" { cap confirm number `1' if _rc { di "{err}`var': invalid lower boundary '`1''" exit 198 } local 2 =`1' local 1 `min' di "{res}`var'{txt}: lower boundary set to {res}`min'" } if `j' ==`nrows' & "`2'" =="" { if "`max'" =="1" local max ``max'' cap confirm number `1' if _rc { di "{err}`var': invalid '`1''" exit 198 } local 2 =`max' di "{res}`var'{txt}: upper boundary set to {res}`max'" } /*1 contains lower 2 upper bound*/ cap mat `xbar'[`j',1] =(`1' + `2') / 2 /*calculate median additionally*/ if "`median'" !="" { if `lvl' ==`med_cl' { qui ta `var' if `var' <`med_cl' & `touse' [`weight'`exp'] local f_pre =r(N) local f_med =`frq'[`j',1] local med /// =`1' + ((`n'/2 - `f_pre') / `f_med') * (`2' - `1') ret scal p50_`var' =`med' } } } /*calculate mean and sd*/ mat `m' =(`xbar'' * `frq') / `n' //mean /*sd*/ mat `tmp' =J(`nrows',1,`m'[1,1]) //constant vextor mean mat `sd' =vecdiag((`xbar' - `tmp') * (`xbar' -`tmp')')' mat `sd' =1/(`n'-1) * (`sd'' * `frq') mat `sd' =sqrt(`sd'[1,1]) /*add to output matrix*/ mat `M'[`++varcount',1] =`m' mat `M'[`varcount',2] =`sd' if "`median'" !="" { mat `M'[`varcount',3] =`med' mat `M'[`varcount',4] =`n' } else mat `M'[`varcount',3] =`n' /*return results in scalars*/ ret scal N_`var' =`n' ret scal sd_`var' =`sd'[1,1] ret scal mean_`var' =`m'[1,1] } /*output*/ mat coln `M' =Mean SD `p50' Obs cap mat rown `M' =`listofnames' if "`dpis'" != "`comma'" set dp `comma' matlist `M' ,format(`format') tw(`txtw') if c(dp) !="`dpis'" set dp `dpis' /*opt ret matrix*/ if `"`matrix'"' !="" ret mat `matrix' =`M' end