*! version 1.1.0 NJC 10 Apr 1997 STB-37 gr26 program define binsm version 4.0 local varlist "req ex min(2) max(2)" local if "opt" local in "opt" #delimit ; local options "Width(real 1) Bin(int 0) STarts(str) SF(str) SONLY Quantile(int 0) XLAbel(str) YLAbel(str) Connect(str) Symbol(str) SOrt Gap(int 6) L1title(str) B2title(str) *" ; #delimit cr parse "`*'" parse "`varlist'", parse(" ") preserve if "`if'`in'" != "" { qui keep `if' `in' } keep `varlist' tempvar xl Y X if "`l1title'" == "" { local l1title : variable label `1' if "`l1title'" == "" { local l1title "`1'" } } if "`b2title'" == "" { local b2title : variable label `2' if "`b2title'" == "" { local b2title "`2'" } } if "`connect'" == "" { local connect ".JJJJJJJJJJJJJJJJJJJ" } if "`symbol'" == "" { local symbol "oiiiiiiiiiiiiiiiiiii" } if "`xlabel'" == "" { local xlabel "xla" } else { local xlabel "xlabel(`xlabel')" } if "`ylabel'" == "" { local ylabel "yla" } else { local ylabel "ylabel(`ylabel')" } local y `1' local x `2' parse "`starts'", parse(",") local starts while "`1'" != "" { if "`1'" == "," { local 1 " " } local starts "`starts'`1'" mac shift } parse "`starts'", parse(" ") local nstarts : word count `starts' if `nstarts' > 1 { qui gen `xl' = . sort `x' local i = _N local j = `nstarts' while `i' >= 1 & `j' >= 1 { local startj : word `j' of `starts' if `x'[`i'] >= `startj' { qui replace `xl' = `startj' in `i' local i = `i' - 1 } else local j = `j' - 1 } qui su `x' qui replace `xl' = _result(5) if `xl' == . local needmax 0 } else if `quantile' > 0 { qui gen `xl' = . sort `x' _pctile `x', nquantiles(`quantile') local i = _N local j = `quantile' while `i' >= 1 & `j' >= 1 { if `x'[`i'] >= _result(`j') { qui replace `xl' = _result(`j') in `i' local i = `i' - 1 } else local j = `j' - 1 } * the preceding 9 lines apparently faster than: * qui for 1-`quantile', ltype(n): replace `xl' = _result(@) /* * */ if `x' >= _result(@) qui su `x' qui replace `xl' = _result(5) if `xl' == . local needmax 0 } else if "`starts'" == "" & `bin' > 0 { qui su `x' local width = (_result(6) - _result(5))/`bin' gen `xl' = autocode(`x',`bin',_result(5),_result(6)) - `width' local needmax 0 } else if "`starts'" != "" & `nstarts' == 1 { qui su `x' local bin = 1 + int((_result(6) - `starts')/`width') gen `xl' = autocode(`x',`bin',`starts',`starts'+`bin'*`width') /* */ - `width' qui replace `xl' = _result(5) if `x' < `xl' local needmax 1 } else { gen `xl' = round(`x', `width') - 0.5 * `width' local needmax 1 } if "`sf'" == "" { local sf "mean" } parse "`sf'", parse(" ") local ns : word count `sf' if `ns' > 19 { di in r "too many smooth variables for graph" exit 198 } local i = 1 while `i' <= `ns' { tempvar ysm`i' YSM`i' local sf`i' : word `i' of `sf' if substr("`sf`i''",1,1) == "p" { local pc = substr("`sf`i''",2,.) if "`pc'" == "ctile" { local p } else { capture assert `pc' > 0 & `pc' < 100 if _rc == 0 { capture confirm integer number `pc' if _rc == 0 { local p "p(`pc')" local sf`i' "pctile" } else { local p } } else { local p } } } else { local p } qui egen `ysm`i'' = `sf`i''(`y'), by(`xl') `p' local sm "`sm' `ysm`i''" local SM "`SM' `YSM`i''" local i = `i' + 1 } sort `xl' qui by `xl' : replace `xl' = . if _n > 1 stack `y' `sm' `x' `y' `sm' `xl', into(`Y' `SM' `X') clear qui replace `Y' = . if _stack == 2 qui drop if `X' == . qui if `needmax' { expand 1 + (_n == _N) replace `X' = `X' + `width' in l } * user sort option is ignored sort `X' _stack qui if "`sonly'" == "sonly" { replace `Y' = . keep if _stack == 2 | _n == _N } gra `Y' `SM' `X', `xlabel' `ylabel' sy(`symbol') c(`connect') /* */ b2("`b2title'") l1("`l1title'") gap(`gap') `options' end