*! version 1.1.15 MLB 22Mar2012 * version 1.1.14 MLB 13Mar2012 * version 1.1.1 MLB 15Jul2009 * change the way the certification option works * let the levels() be specified in seqlogit * version 1.1.0 MLB 23Okt2008 * fix bug in weight computation (no longer ignore the levels() option) * version 1.0.5 MLB 24Aug2008 * simplify the syntax * version 1.0.4 MLB 19Okt2007 * add -exact- to -confirm variable- in line 176 * version 1.0.3 MLB 24Aug2007 * decreased the fontsize of the legend * version 1.0.1 MLB 10Aug2007 * version 1.0.0 MLB 21May2007 program define seqlogitdecomp10, rclass syntax , /// overat(string) /// [ /// at(string) /// SUBTitle(string asis) /// EQLabel(string asis) /// EQLEGEND /// XLine(passthru) /// YLine(passthru) /// TItle(passthru) /// NAme(string asis) /// YSCale(passthru) /// YLABel(passthru) /// XSCale(passthru) /// XLABel(passthru) /// YSIZe(passthru) /// XSIZe(passthru) /// certify /// ] /* parse name */ if "`name'" != "" { gettoken grname : name if substr("`grname'", -1,.) == "," { local lgrname = length("`grname'") - 1 local grname = substr("`grname'", 1, `lgrname') } local name `"name(`name')"' } else local grname "Graph" /* parse general */ if "`e(cmd)'" != "seqlogit10" { di as err "seqlogitdecomp10 can only be used after seqlogit10" exit 198 } if "`e(ofinterest)'" == "" { di as err /// "seqlogitdecomp10 can only be used when the ofinterest option is specified in seqlogit10" } /*Parse overat & deal with default subtitles*/ // split overat() local k = 0 while `"`overat'"' != "" { local `k++' gettoken left overat : overat, parse(",") local overat`k' `left' gettoken comma overat : overat, parse(",") } local k_overat `k' // check if # elements is even forvalues i = 1/`k_overat' { local even : word count `overat`k'' local even = `even' / 2 capture confirm integer number `even' if _rc { di as err "option overat() must contain an even number of elements" exit 198 } } // check if odd elements are variables and even elements are numbers forvalues i = 1/`k_overat' { local j = 0 foreach l of local overat`i' { if mod(`++j',2) == 1 { capture unab var : `l' if _rc { di as err "every odd element of option overat() should be a variable" exit 198 } capture unab var : `l', max(1) if _rc { di as err "`l' in option overat() is an ambiguous abbreviation" exit 111 } } if mod(`j',2) == 0 { capture confirm number `l' if _rc { capture confirm scalar `l' if _rc { di as err "every even element in option overat() should be a number" exit 198 } } } } } // subtitles if `"`subtitle'"' == "" { forvalues i = 1/`k_overat' { local s : word 2 of `overat`i'' local subtitle `"`subtitle' `s'"' } } // add interaction terms between ofinterest() and over() local over `e(over)' local ofinterest `e(ofinterest)' local posinat : list posof "`ofinterest'" in at if `posinat' == 0 { sum `ofinterest' if e(sample), meanonly local valinat = r(mean) } else { local posinat = `posinat' + 1 local valinat : word `posinat' of `at' } forvalues i = 1/`k_overat' { foreach k of local over { if `: list posof "_`ofinterest'_X_`k'" in overat`i'' == 0 { local posinoverat : list posof "`k'" in overat`i' if `posinoverat' == 0 { di as err /// "the overat option needs to specify values for the variable(s) `over'" exit 198 } local posinoverat = `posinoverat' + 1 local valinoverat : word `posinoverat' of `overat`i'' local val = `valinoverat'*`valinat' local overat`i' "`overat`i'' _`ofinterest'_X_`k' `val'" } } } local overat "`overat1'" forvalues i = 2/`k_overat' { local overat "`overat', `overat`i''" } /*Parse Overlodds*/ local overlodds "_b[`e(ofinterest)']" foreach k of local over { local overlodds "`overlodds' + _b[_`ofinterest'_X_`k']*`k'" } /*Parse other options*/ if `"`subtitle'"' != `""' { local k_title : word count `subtitle' if `k_overat' != `k_title' { di as error /* */ "number of subtitles should equal the number of comparisons specified in overat()" exit 198 } } if `"`eqlabel'"' != `""' { local k_lab : word count `eqlabel' if `k_lab' != `e(k_eq)' { di as error /* */ "number of labels specified in eqlabel() should equal the number of equations" exit 198 } } if "`toteffect'" != "" { local k_toteffect : word count `toteffect' if `k_toteffect' != 2 { di as error /// "2 new variable names must be specified in the option toteffect()" exit 198 } confirm new variable `toteffect' } /* Get a list of all variables in model that are not specified in at() or overat() and store their means in locals */ local k_at : word count `at' local end = `k_at'-1 tokenize `at' forvalues i = 1(2)`end' { local j = `i' + 1 unab var : ``i'' local at2 "`at2' `var' ``j''" local out "`out' `var'" } tempname b matrix `b' = e(b) local in : colnames `b' local in : list uniq in local cons "_cons" local in : list in - cons local in : list in - out local overvarst : subinstr local overat "," "", all local m = 1 foreach loc of local overvarst { if mod(`m++',2) == 1 { local overvars "`overvars' `loc'" } } local overvars : list uniq overvars local in : list in - overvars foreach var of local in { sum `var' if e(sample), meanonly local m`var' = r(mean) } /*Create a resultset ("dataset" containing results)*/ preserve qui { drop _all set obs `k_overat' // create variables specified in at tokenize `at2' forvalues i = 1(2)`end' { local j = `i' + 1 gen ``i'' = ``j'' } // fill in non-specified variables with their mean foreach var of local in { gen `var' = `m`var'' } // create variables specified in overat foreach var of local overvars { gen `var' = . } forvalues i = 1/`k_overat' { tokenize `overat`i'' local k : word count `overat`i'' local end = `k' - 1 forvalues j = 1(2)`end' { local l = `j' + 1 replace ``j'' = ``l'' in `i' } } // predict weights forvalues i = 1/`e(k_eq)' { local w "`w' w`i'" } predict `w', trweight // log odds forvalues i = 1/`e(k_eq)' { local lodds : subinstr local overlodds "_b[" "[#`i']_b[", all gen lodds`i' = `lodds' } // reshape the data gen group = _n expand 2 gen first = _n <= `k_overat' forvalues i = 1/`e(k_eq)' { replace w`i' = 0 if first } gen zero = 0 expand `e(k_eq)' bys first group : gen byte tr = _n forvalues i = 1/`e(k_eq)' { replace w`i' = 0 if tr != `i' replace lodds`i' = 0 if tr != `i' local graph "`graph' (rarea zero lodds`i' w`i')" } replace tr = -tr sort tr group first gen byby = ceil(_n/2) tokenize `"`subtitle'"' forvalues i = 1/`k_overat' { label define byby `i' "``i''", add } local begin = `k_overat' + 1 local end = `e(k_eq)'*`k_overat' forvalues i = `begin'/`end' { label define byby `i' " ", add } label values byby byby if `"`eqlabel'"' == `""' { forvalues i = 1 / `e(Ntrans)' { local endeq = `e(Nchoice`i')' - 1 forvalues j = 1/`endeq' { local eqlabel `"`eqlabel' "`e(tr`i'choice`j')' v `e(tr`i'choice0)'""' } } } if "`eqlegend'" != "" { tokenize `"`eqlabel'"' forvalues i = 1/`e(k_eq)' { local lab `"`lab' label (`i' ``i'')"' } forvalues i = 1/`e(k_eq)' { local order "`i' `order'" } local leg `"legend( `lab' order(`order') size(small) symysize(*.75) symxsize(*.5) )"' } else { local legoff "off" } twoway `graph' , by(byby, col(`k_overat') compact /* */ note("") legend(pos(4) `legoff') `title' ) /* */ ylabel(,nogrid) /* */ `leg' /* */ ytitle("log odds ratio", size(small)) /* */ xtitle("weight", size(small)) `xline' `yline' /* */ `name' `yscale' `ylabel' `xscale' `xlabel' `ysize' `xsize' nodraw local eqlabel : list clean eqlabel tokenize `"`eqlabel'"' // add titles for transitions at the right of the graph local i = 1 forvalues j = `end'(`=-1*`k_overat'')`k_overat'{ _gm_edit .`grname'.plotregion1.r1title[`j'].text = {} _gm_edit .`grname'.plotregion1.r1title[`j']._set_orientation rvertical _gm_edit .`grname'.plotregion1.r1title[`j'].style.editstyle drawbox(yes) editcopy gettoken left : `i', qed(quote) if `quote' { while `"``i''"' != "" { gettoken part `i' : `i' _gm_edit .`grname'.plotregion1.r1title[`j'].text.Arrpush `"`part'"' } } else { _gm_edit .`grname'.plotregion1.r1title[`j'].text.Arrpush `"``i''"' } _gm_edit .`grname'.plotregion1.r1title[`j'].as_textbox.setstyle, style(yes) local `i++' } graph display `grname' if "`certify'" != "" { tempname resultset mkmat _all, matrix(`resultset') return matrix resultset = `resultset' } restore } end